| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 // Load a video frame from disk. | 75 // Load a video frame from disk. |
| 76 bool LoadFrameNoRepeat(T* frame) { | 76 bool LoadFrameNoRepeat(T* frame) { |
| 77 int save_repeat = repeat_; // This LoadFrame disables repeat. | 77 int save_repeat = repeat_; // This LoadFrame disables repeat. |
| 78 repeat_ = 1; | 78 repeat_ = 1; |
| 79 bool success = LoadFrame(kImageFilename, cricket::FOURCC_I420, | 79 bool success = LoadFrame(kImageFilename, cricket::FOURCC_I420, |
| 80 kWidth, kHeight, frame); | 80 kWidth, kHeight, frame); |
| 81 repeat_ = save_repeat; | 81 repeat_ = save_repeat; |
| 82 return success; | 82 return success; |
| 83 } | 83 } |
| 84 | 84 |
| 85 bool LoadFrame(const std::string& filename, uint32 format, | 85 bool LoadFrame(const std::string& filename, |
| 86 int32 width, int32 height, T* frame) { | 86 uint32_t format, |
| 87 int32_t width, |
| 88 int32_t height, |
| 89 T* frame) { |
| 87 return LoadFrame(filename, format, width, height, width, abs(height), | 90 return LoadFrame(filename, format, width, height, width, abs(height), |
| 88 webrtc::kVideoRotation_0, frame); | 91 webrtc::kVideoRotation_0, frame); |
| 89 } | 92 } |
| 90 bool LoadFrame(const std::string& filename, | 93 bool LoadFrame(const std::string& filename, |
| 91 uint32 format, | 94 uint32_t format, |
| 92 int32 width, | 95 int32_t width, |
| 93 int32 height, | 96 int32_t height, |
| 94 int dw, | 97 int dw, |
| 95 int dh, | 98 int dh, |
| 96 webrtc::VideoRotation rotation, | 99 webrtc::VideoRotation rotation, |
| 97 T* frame) { | 100 T* frame) { |
| 98 rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(filename)); | 101 rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(filename)); |
| 99 return LoadFrame(ms.get(), format, width, height, dw, dh, rotation, frame); | 102 return LoadFrame(ms.get(), format, width, height, dw, dh, rotation, frame); |
| 100 } | 103 } |
| 101 // Load a video frame from a memory stream. | 104 // Load a video frame from a memory stream. |
| 102 bool LoadFrame(rtc::MemoryStream* ms, uint32 format, | 105 bool LoadFrame(rtc::MemoryStream* ms, |
| 103 int32 width, int32 height, T* frame) { | 106 uint32_t format, |
| 107 int32_t width, |
| 108 int32_t height, |
| 109 T* frame) { |
| 104 return LoadFrame(ms, format, width, height, width, abs(height), | 110 return LoadFrame(ms, format, width, height, width, abs(height), |
| 105 webrtc::kVideoRotation_0, frame); | 111 webrtc::kVideoRotation_0, frame); |
| 106 } | 112 } |
| 107 bool LoadFrame(rtc::MemoryStream* ms, | 113 bool LoadFrame(rtc::MemoryStream* ms, |
| 108 uint32 format, | 114 uint32_t format, |
| 109 int32 width, | 115 int32_t width, |
| 110 int32 height, | 116 int32_t height, |
| 111 int dw, | 117 int dw, |
| 112 int dh, | 118 int dh, |
| 113 webrtc::VideoRotation rotation, | 119 webrtc::VideoRotation rotation, |
| 114 T* frame) { | 120 T* frame) { |
| 115 if (!ms) { | 121 if (!ms) { |
| 116 return false; | 122 return false; |
| 117 } | 123 } |
| 118 size_t data_size; | 124 size_t data_size; |
| 119 bool ret = ms->GetSize(&data_size); | 125 bool ret = ms->GetSize(&data_size); |
| 120 EXPECT_TRUE(ret); | 126 EXPECT_TRUE(ret); |
| 121 if (ret) { | 127 if (ret) { |
| 122 ret = LoadFrame(reinterpret_cast<uint8*>(ms->GetBuffer()), data_size, | 128 ret = LoadFrame(reinterpret_cast<uint8_t*>(ms->GetBuffer()), data_size, |
| 123 format, width, height, dw, dh, rotation, frame); | 129 format, width, height, dw, dh, rotation, frame); |
| 124 } | 130 } |
| 125 return ret; | 131 return ret; |
| 126 } | 132 } |
| 127 // Load a frame from a raw buffer. | 133 // Load a frame from a raw buffer. |
| 128 bool LoadFrame(uint8* sample, size_t sample_size, uint32 format, | 134 bool LoadFrame(uint8_t* sample, |
| 129 int32 width, int32 height, T* frame) { | 135 size_t sample_size, |
| 136 uint32_t format, |
| 137 int32_t width, |
| 138 int32_t height, |
| 139 T* frame) { |
| 130 return LoadFrame(sample, sample_size, format, width, height, width, | 140 return LoadFrame(sample, sample_size, format, width, height, width, |
| 131 abs(height), webrtc::kVideoRotation_0, frame); | 141 abs(height), webrtc::kVideoRotation_0, frame); |
| 132 } | 142 } |
| 133 bool LoadFrame(uint8* sample, | 143 bool LoadFrame(uint8_t* sample, |
| 134 size_t sample_size, | 144 size_t sample_size, |
| 135 uint32 format, | 145 uint32_t format, |
| 136 int32 width, | 146 int32_t width, |
| 137 int32 height, | 147 int32_t height, |
| 138 int dw, | 148 int dw, |
| 139 int dh, | 149 int dh, |
| 140 webrtc::VideoRotation rotation, | 150 webrtc::VideoRotation rotation, |
| 141 T* frame) { | 151 T* frame) { |
| 142 bool ret = false; | 152 bool ret = false; |
| 143 for (int i = 0; i < repeat_; ++i) { | 153 for (int i = 0; i < repeat_; ++i) { |
| 144 ret = frame->Init(format, width, height, dw, dh, | 154 ret = frame->Init(format, width, height, dw, dh, |
| 145 sample, sample_size, 1, 1, 0, rotation); | 155 sample, sample_size, 1, 1, 0, rotation); |
| 146 } | 156 } |
| 147 return ret; | 157 return ret; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 171 } | 181 } |
| 172 | 182 |
| 173 // Write an I420 frame out to disk. | 183 // Write an I420 frame out to disk. |
| 174 bool DumpFrame(const std::string& prefix, | 184 bool DumpFrame(const std::string& prefix, |
| 175 const cricket::VideoFrame& frame) { | 185 const cricket::VideoFrame& frame) { |
| 176 char filename[256]; | 186 char filename[256]; |
| 177 rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv", | 187 rtc::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv", |
| 178 prefix.c_str(), frame.GetWidth(), frame.GetHeight()); | 188 prefix.c_str(), frame.GetWidth(), frame.GetHeight()); |
| 179 size_t out_size = cricket::VideoFrame::SizeOf(frame.GetWidth(), | 189 size_t out_size = cricket::VideoFrame::SizeOf(frame.GetWidth(), |
| 180 frame.GetHeight()); | 190 frame.GetHeight()); |
| 181 rtc::scoped_ptr<uint8[]> out(new uint8[out_size]); | 191 rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size]); |
| 182 frame.CopyToBuffer(out.get(), out_size); | 192 frame.CopyToBuffer(out.get(), out_size); |
| 183 return DumpSample(filename, out.get(), out_size); | 193 return DumpSample(filename, out.get(), out_size); |
| 184 } | 194 } |
| 185 | 195 |
| 186 bool DumpSample(const std::string& filename, const void* buffer, int size) { | 196 bool DumpSample(const std::string& filename, const void* buffer, int size) { |
| 187 rtc::Pathname path(filename); | 197 rtc::Pathname path(filename); |
| 188 rtc::scoped_ptr<rtc::FileStream> fs( | 198 rtc::scoped_ptr<rtc::FileStream> fs( |
| 189 rtc::Filesystem::OpenFile(path, "wb")); | 199 rtc::Filesystem::OpenFile(path, "wb")); |
| 190 if (!fs.get()) { | 200 if (!fs.get()) { |
| 191 return false; | 201 return false; |
| 192 } | 202 } |
| 193 | 203 |
| 194 return (fs->Write(buffer, size, NULL, NULL) == rtc::SR_SUCCESS); | 204 return (fs->Write(buffer, size, NULL, NULL) == rtc::SR_SUCCESS); |
| 195 } | 205 } |
| 196 | 206 |
| 197 // Create a test image in the desired color space. | 207 // Create a test image in the desired color space. |
| 198 // The image is a checkerboard pattern with 63x63 squares, which allows | 208 // The image is a checkerboard pattern with 63x63 squares, which allows |
| 199 // I420 chroma artifacts to easily be seen on the square boundaries. | 209 // I420 chroma artifacts to easily be seen on the square boundaries. |
| 200 // The pattern is { { green, orange }, { blue, purple } } | 210 // The pattern is { { green, orange }, { blue, purple } } |
| 201 // There is also a gradient within each square to ensure that the luma | 211 // There is also a gradient within each square to ensure that the luma |
| 202 // values are handled properly. | 212 // values are handled properly. |
| 203 rtc::MemoryStream* CreateYuv422Sample(uint32 fourcc, | 213 rtc::MemoryStream* CreateYuv422Sample(uint32_t fourcc, |
| 204 uint32 width, uint32 height) { | 214 uint32_t width, |
| 215 uint32_t height) { |
| 205 int y1_pos, y2_pos, u_pos, v_pos; | 216 int y1_pos, y2_pos, u_pos, v_pos; |
| 206 if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) { | 217 if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) { |
| 207 return NULL; | 218 return NULL; |
| 208 } | 219 } |
| 209 | 220 |
| 210 rtc::scoped_ptr<rtc::MemoryStream> ms( | 221 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 211 new rtc::MemoryStream); | 222 new rtc::MemoryStream); |
| 212 int awidth = (width + 1) & ~1; | 223 int awidth = (width + 1) & ~1; |
| 213 int size = awidth * 2 * height; | 224 int size = awidth * 2 * height; |
| 214 if (!ms->ReserveSize(size)) { | 225 if (!ms->ReserveSize(size)) { |
| 215 return NULL; | 226 return NULL; |
| 216 } | 227 } |
| 217 for (uint32 y = 0; y < height; ++y) { | 228 for (uint32_t y = 0; y < height; ++y) { |
| 218 for (int x = 0; x < awidth; x += 2) { | 229 for (int x = 0; x < awidth; x += 2) { |
| 219 uint8 quad[4]; | 230 uint8_t quad[4]; |
| 220 quad[y1_pos] = (x % 63 + y % 63) + 64; | 231 quad[y1_pos] = (x % 63 + y % 63) + 64; |
| 221 quad[y2_pos] = ((x + 1) % 63 + y % 63) + 64; | 232 quad[y2_pos] = ((x + 1) % 63 + y % 63) + 64; |
| 222 quad[u_pos] = ((x / 63) & 1) ? 192 : 64; | 233 quad[u_pos] = ((x / 63) & 1) ? 192 : 64; |
| 223 quad[v_pos] = ((y / 63) & 1) ? 192 : 64; | 234 quad[v_pos] = ((y / 63) & 1) ? 192 : 64; |
| 224 ms->Write(quad, sizeof(quad), NULL, NULL); | 235 ms->Write(quad, sizeof(quad), NULL, NULL); |
| 225 } | 236 } |
| 226 } | 237 } |
| 227 return ms.release(); | 238 return ms.release(); |
| 228 } | 239 } |
| 229 | 240 |
| 230 // Create a test image for YUV 420 formats with 12 bits per pixel. | 241 // Create a test image for YUV 420 formats with 12 bits per pixel. |
| 231 rtc::MemoryStream* CreateYuvSample(uint32 width, uint32 height, | 242 rtc::MemoryStream* CreateYuvSample(uint32_t width, |
| 232 uint32 bpp) { | 243 uint32_t height, |
| 244 uint32_t bpp) { |
| 233 rtc::scoped_ptr<rtc::MemoryStream> ms( | 245 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 234 new rtc::MemoryStream); | 246 new rtc::MemoryStream); |
| 235 if (!ms->ReserveSize(width * height * bpp / 8)) { | 247 if (!ms->ReserveSize(width * height * bpp / 8)) { |
| 236 return NULL; | 248 return NULL; |
| 237 } | 249 } |
| 238 | 250 |
| 239 for (uint32 i = 0; i < width * height * bpp / 8; ++i) { | 251 for (uint32_t i = 0; i < width * height * bpp / 8; ++i) { |
| 240 char value = ((i / 63) & 1) ? 192 : 64; | 252 char value = ((i / 63) & 1) ? 192 : 64; |
| 241 ms->Write(&value, sizeof(value), NULL, NULL); | 253 ms->Write(&value, sizeof(value), NULL, NULL); |
| 242 } | 254 } |
| 243 return ms.release(); | 255 return ms.release(); |
| 244 } | 256 } |
| 245 | 257 |
| 246 rtc::MemoryStream* CreateRgbSample(uint32 fourcc, | 258 rtc::MemoryStream* CreateRgbSample(uint32_t fourcc, |
| 247 uint32 width, uint32 height) { | 259 uint32_t width, |
| 260 uint32_t height) { |
| 248 int r_pos, g_pos, b_pos, bytes; | 261 int r_pos, g_pos, b_pos, bytes; |
| 249 if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) { | 262 if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) { |
| 250 return NULL; | 263 return NULL; |
| 251 } | 264 } |
| 252 | 265 |
| 253 rtc::scoped_ptr<rtc::MemoryStream> ms( | 266 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 254 new rtc::MemoryStream); | 267 new rtc::MemoryStream); |
| 255 if (!ms->ReserveSize(width * height * bytes)) { | 268 if (!ms->ReserveSize(width * height * bytes)) { |
| 256 return NULL; | 269 return NULL; |
| 257 } | 270 } |
| 258 | 271 |
| 259 for (uint32 y = 0; y < height; ++y) { | 272 for (uint32_t y = 0; y < height; ++y) { |
| 260 for (uint32 x = 0; x < width; ++x) { | 273 for (uint32_t x = 0; x < width; ++x) { |
| 261 uint8 rgb[4] = { 255, 255, 255, 255 }; | 274 uint8_t rgb[4] = {255, 255, 255, 255}; |
| 262 rgb[r_pos] = ((x / 63) & 1) ? 224 : 32; | 275 rgb[r_pos] = ((x / 63) & 1) ? 224 : 32; |
| 263 rgb[g_pos] = (x % 63 + y % 63) + 96; | 276 rgb[g_pos] = (x % 63 + y % 63) + 96; |
| 264 rgb[b_pos] = ((y / 63) & 1) ? 224 : 32; | 277 rgb[b_pos] = ((y / 63) & 1) ? 224 : 32; |
| 265 ms->Write(rgb, bytes, NULL, NULL); | 278 ms->Write(rgb, bytes, NULL, NULL); |
| 266 } | 279 } |
| 267 } | 280 } |
| 268 return ms.release(); | 281 return ms.release(); |
| 269 } | 282 } |
| 270 | 283 |
| 271 // Simple conversion routines to verify the optimized VideoFrame routines. | 284 // Simple conversion routines to verify the optimized VideoFrame routines. |
| 272 // Converts from the specified colorspace to I420. | 285 // Converts from the specified colorspace to I420. |
| 273 bool ConvertYuv422(const rtc::MemoryStream* ms, | 286 bool ConvertYuv422(const rtc::MemoryStream* ms, |
| 274 uint32 fourcc, uint32 width, uint32 height, | 287 uint32_t fourcc, |
| 288 uint32_t width, |
| 289 uint32_t height, |
| 275 T* frame) { | 290 T* frame) { |
| 276 int y1_pos, y2_pos, u_pos, v_pos; | 291 int y1_pos, y2_pos, u_pos, v_pos; |
| 277 if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) { | 292 if (!GetYuv422Packing(fourcc, &y1_pos, &y2_pos, &u_pos, &v_pos)) { |
| 278 return false; | 293 return false; |
| 279 } | 294 } |
| 280 | 295 |
| 281 const uint8* start = reinterpret_cast<const uint8*>(ms->GetBuffer()); | 296 const uint8_t* start = reinterpret_cast<const uint8_t*>(ms->GetBuffer()); |
| 282 int awidth = (width + 1) & ~1; | 297 int awidth = (width + 1) & ~1; |
| 283 frame->InitToBlack(width, height, 1, 1, 0); | 298 frame->InitToBlack(width, height, 1, 1, 0); |
| 284 int stride_y = frame->GetYPitch(); | 299 int stride_y = frame->GetYPitch(); |
| 285 int stride_u = frame->GetUPitch(); | 300 int stride_u = frame->GetUPitch(); |
| 286 int stride_v = frame->GetVPitch(); | 301 int stride_v = frame->GetVPitch(); |
| 287 for (uint32 y = 0; y < height; ++y) { | 302 for (uint32_t y = 0; y < height; ++y) { |
| 288 for (uint32 x = 0; x < width; x += 2) { | 303 for (uint32_t x = 0; x < width; x += 2) { |
| 289 const uint8* quad1 = start + (y * awidth + x) * 2; | 304 const uint8_t* quad1 = start + (y * awidth + x) * 2; |
| 290 frame->GetYPlane()[stride_y * y + x] = quad1[y1_pos]; | 305 frame->GetYPlane()[stride_y * y + x] = quad1[y1_pos]; |
| 291 if ((x + 1) < width) { | 306 if ((x + 1) < width) { |
| 292 frame->GetYPlane()[stride_y * y + x + 1] = quad1[y2_pos]; | 307 frame->GetYPlane()[stride_y * y + x + 1] = quad1[y2_pos]; |
| 293 } | 308 } |
| 294 if ((y & 1) == 0) { | 309 if ((y & 1) == 0) { |
| 295 const uint8* quad2 = quad1 + awidth * 2; | 310 const uint8_t* quad2 = quad1 + awidth * 2; |
| 296 if ((y + 1) >= height) { | 311 if ((y + 1) >= height) { |
| 297 quad2 = quad1; | 312 quad2 = quad1; |
| 298 } | 313 } |
| 299 frame->GetUPlane()[stride_u * (y / 2) + x / 2] = | 314 frame->GetUPlane()[stride_u * (y / 2) + x / 2] = |
| 300 (quad1[u_pos] + quad2[u_pos] + 1) / 2; | 315 (quad1[u_pos] + quad2[u_pos] + 1) / 2; |
| 301 frame->GetVPlane()[stride_v * (y / 2) + x / 2] = | 316 frame->GetVPlane()[stride_v * (y / 2) + x / 2] = |
| 302 (quad1[v_pos] + quad2[v_pos] + 1) / 2; | 317 (quad1[v_pos] + quad2[v_pos] + 1) / 2; |
| 303 } | 318 } |
| 304 } | 319 } |
| 305 } | 320 } |
| 306 return true; | 321 return true; |
| 307 } | 322 } |
| 308 | 323 |
| 309 // Convert RGB to 420. | 324 // Convert RGB to 420. |
| 310 // A negative height inverts the image. | 325 // A negative height inverts the image. |
| 311 bool ConvertRgb(const rtc::MemoryStream* ms, | 326 bool ConvertRgb(const rtc::MemoryStream* ms, |
| 312 uint32 fourcc, int32 width, int32 height, | 327 uint32_t fourcc, |
| 328 int32_t width, |
| 329 int32_t height, |
| 313 T* frame) { | 330 T* frame) { |
| 314 int r_pos, g_pos, b_pos, bytes; | 331 int r_pos, g_pos, b_pos, bytes; |
| 315 if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) { | 332 if (!GetRgbPacking(fourcc, &r_pos, &g_pos, &b_pos, &bytes)) { |
| 316 return false; | 333 return false; |
| 317 } | 334 } |
| 318 int pitch = width * bytes; | 335 int pitch = width * bytes; |
| 319 const uint8* start = reinterpret_cast<const uint8*>(ms->GetBuffer()); | 336 const uint8_t* start = reinterpret_cast<const uint8_t*>(ms->GetBuffer()); |
| 320 if (height < 0) { | 337 if (height < 0) { |
| 321 height = -height; | 338 height = -height; |
| 322 start = start + pitch * (height - 1); | 339 start = start + pitch * (height - 1); |
| 323 pitch = -pitch; | 340 pitch = -pitch; |
| 324 } | 341 } |
| 325 frame->InitToBlack(width, height, 1, 1, 0); | 342 frame->InitToBlack(width, height, 1, 1, 0); |
| 326 int stride_y = frame->GetYPitch(); | 343 int stride_y = frame->GetYPitch(); |
| 327 int stride_u = frame->GetUPitch(); | 344 int stride_u = frame->GetUPitch(); |
| 328 int stride_v = frame->GetVPitch(); | 345 int stride_v = frame->GetVPitch(); |
| 329 for (int32 y = 0; y < height; y += 2) { | 346 for (int32_t y = 0; y < height; y += 2) { |
| 330 for (int32 x = 0; x < width; x += 2) { | 347 for (int32_t x = 0; x < width; x += 2) { |
| 331 const uint8* rgb[4]; | 348 const uint8_t* rgb[4]; |
| 332 uint8 yuv[4][3]; | 349 uint8_t yuv[4][3]; |
| 333 rgb[0] = start + y * pitch + x * bytes; | 350 rgb[0] = start + y * pitch + x * bytes; |
| 334 rgb[1] = rgb[0] + ((x + 1) < width ? bytes : 0); | 351 rgb[1] = rgb[0] + ((x + 1) < width ? bytes : 0); |
| 335 rgb[2] = rgb[0] + ((y + 1) < height ? pitch : 0); | 352 rgb[2] = rgb[0] + ((y + 1) < height ? pitch : 0); |
| 336 rgb[3] = rgb[2] + ((x + 1) < width ? bytes : 0); | 353 rgb[3] = rgb[2] + ((x + 1) < width ? bytes : 0); |
| 337 for (size_t i = 0; i < 4; ++i) { | 354 for (size_t i = 0; i < 4; ++i) { |
| 338 ConvertRgbPixel(rgb[i][r_pos], rgb[i][g_pos], rgb[i][b_pos], | 355 ConvertRgbPixel(rgb[i][r_pos], rgb[i][g_pos], rgb[i][b_pos], |
| 339 &yuv[i][0], &yuv[i][1], &yuv[i][2]); | 356 &yuv[i][0], &yuv[i][1], &yuv[i][2]); |
| 340 } | 357 } |
| 341 frame->GetYPlane()[stride_y * y + x] = yuv[0][0]; | 358 frame->GetYPlane()[stride_y * y + x] = yuv[0][0]; |
| 342 if ((x + 1) < width) { | 359 if ((x + 1) < width) { |
| 343 frame->GetYPlane()[stride_y * y + x + 1] = yuv[1][0]; | 360 frame->GetYPlane()[stride_y * y + x + 1] = yuv[1][0]; |
| 344 } | 361 } |
| 345 if ((y + 1) < height) { | 362 if ((y + 1) < height) { |
| 346 frame->GetYPlane()[stride_y * (y + 1) + x] = yuv[2][0]; | 363 frame->GetYPlane()[stride_y * (y + 1) + x] = yuv[2][0]; |
| 347 if ((x + 1) < width) { | 364 if ((x + 1) < width) { |
| 348 frame->GetYPlane()[stride_y * (y + 1) + x + 1] = yuv[3][0]; | 365 frame->GetYPlane()[stride_y * (y + 1) + x + 1] = yuv[3][0]; |
| 349 } | 366 } |
| 350 } | 367 } |
| 351 frame->GetUPlane()[stride_u * (y / 2) + x / 2] = | 368 frame->GetUPlane()[stride_u * (y / 2) + x / 2] = |
| 352 (yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1] + 2) / 4; | 369 (yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1] + 2) / 4; |
| 353 frame->GetVPlane()[stride_v * (y / 2) + x / 2] = | 370 frame->GetVPlane()[stride_v * (y / 2) + x / 2] = |
| 354 (yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2] + 2) / 4; | 371 (yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2] + 2) / 4; |
| 355 } | 372 } |
| 356 } | 373 } |
| 357 return true; | 374 return true; |
| 358 } | 375 } |
| 359 | 376 |
| 360 // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia. | 377 // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia. |
| 361 void ConvertRgbPixel(uint8 r, uint8 g, uint8 b, | 378 void ConvertRgbPixel(uint8_t r, |
| 362 uint8* y, uint8* u, uint8* v) { | 379 uint8_t g, |
| 380 uint8_t b, |
| 381 uint8_t* y, |
| 382 uint8_t* u, |
| 383 uint8_t* v) { |
| 363 *y = static_cast<int>(.257 * r + .504 * g + .098 * b) + 16; | 384 *y = static_cast<int>(.257 * r + .504 * g + .098 * b) + 16; |
| 364 *u = static_cast<int>(-.148 * r - .291 * g + .439 * b) + 128; | 385 *u = static_cast<int>(-.148 * r - .291 * g + .439 * b) + 128; |
| 365 *v = static_cast<int>(.439 * r - .368 * g - .071 * b) + 128; | 386 *v = static_cast<int>(.439 * r - .368 * g - .071 * b) + 128; |
| 366 } | 387 } |
| 367 | 388 |
| 368 bool GetYuv422Packing(uint32 fourcc, | 389 bool GetYuv422Packing(uint32_t fourcc, |
| 369 int* y1_pos, int* y2_pos, int* u_pos, int* v_pos) { | 390 int* y1_pos, |
| 391 int* y2_pos, |
| 392 int* u_pos, |
| 393 int* v_pos) { |
| 370 if (fourcc == cricket::FOURCC_YUY2) { | 394 if (fourcc == cricket::FOURCC_YUY2) { |
| 371 *y1_pos = 0; *u_pos = 1; *y2_pos = 2; *v_pos = 3; | 395 *y1_pos = 0; *u_pos = 1; *y2_pos = 2; *v_pos = 3; |
| 372 } else if (fourcc == cricket::FOURCC_UYVY) { | 396 } else if (fourcc == cricket::FOURCC_UYVY) { |
| 373 *u_pos = 0; *y1_pos = 1; *v_pos = 2; *y2_pos = 3; | 397 *u_pos = 0; *y1_pos = 1; *v_pos = 2; *y2_pos = 3; |
| 374 } else { | 398 } else { |
| 375 return false; | 399 return false; |
| 376 } | 400 } |
| 377 return true; | 401 return true; |
| 378 } | 402 } |
| 379 | 403 |
| 380 bool GetRgbPacking(uint32 fourcc, | 404 bool GetRgbPacking(uint32_t fourcc, |
| 381 int* r_pos, int* g_pos, int* b_pos, int* bytes) { | 405 int* r_pos, |
| 406 int* g_pos, |
| 407 int* b_pos, |
| 408 int* bytes) { |
| 382 if (fourcc == cricket::FOURCC_RAW) { | 409 if (fourcc == cricket::FOURCC_RAW) { |
| 383 *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 3; // RGB in memory. | 410 *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 3; // RGB in memory. |
| 384 } else if (fourcc == cricket::FOURCC_24BG) { | 411 } else if (fourcc == cricket::FOURCC_24BG) { |
| 385 *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 3; // BGR in memory. | 412 *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 3; // BGR in memory. |
| 386 } else if (fourcc == cricket::FOURCC_ABGR) { | 413 } else if (fourcc == cricket::FOURCC_ABGR) { |
| 387 *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 4; // RGBA in memory. | 414 *r_pos = 0; *g_pos = 1; *b_pos = 2; *bytes = 4; // RGBA in memory. |
| 388 } else if (fourcc == cricket::FOURCC_BGRA) { | 415 } else if (fourcc == cricket::FOURCC_BGRA) { |
| 389 *r_pos = 1; *g_pos = 2; *b_pos = 3; *bytes = 4; // ARGB in memory. | 416 *r_pos = 1; *g_pos = 2; *b_pos = 3; *bytes = 4; // ARGB in memory. |
| 390 } else if (fourcc == cricket::FOURCC_ARGB) { | 417 } else if (fourcc == cricket::FOURCC_ARGB) { |
| 391 *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 4; // BGRA in memory. | 418 *r_pos = 2; *g_pos = 1; *b_pos = 0; *bytes = 4; // BGRA in memory. |
| 392 } else { | 419 } else { |
| 393 return false; | 420 return false; |
| 394 } | 421 } |
| 395 return true; | 422 return true; |
| 396 } | 423 } |
| 397 | 424 |
| 398 // Comparison functions for testing. | 425 // Comparison functions for testing. |
| 399 static bool IsNull(const cricket::VideoFrame& frame) { | 426 static bool IsNull(const cricket::VideoFrame& frame) { |
| 400 return !frame.GetYPlane(); | 427 return !frame.GetYPlane(); |
| 401 } | 428 } |
| 402 | 429 |
| 403 static bool IsSize(const cricket::VideoFrame& frame, | 430 static bool IsSize(const cricket::VideoFrame& frame, |
| 404 uint32 width, uint32 height) { | 431 uint32_t width, |
| 405 return !IsNull(frame) && | 432 uint32_t height) { |
| 406 frame.GetYPitch() >= static_cast<int32>(width) && | 433 return !IsNull(frame) && frame.GetYPitch() >= static_cast<int32_t>(width) && |
| 407 frame.GetUPitch() >= static_cast<int32>(width) / 2 && | 434 frame.GetUPitch() >= static_cast<int32_t>(width) / 2 && |
| 408 frame.GetVPitch() >= static_cast<int32>(width) / 2 && | 435 frame.GetVPitch() >= static_cast<int32_t>(width) / 2 && |
| 409 frame.GetWidth() == width && frame.GetHeight() == height; | 436 frame.GetWidth() == width && frame.GetHeight() == height; |
| 410 } | 437 } |
| 411 | 438 |
| 412 static bool IsPlaneEqual(const std::string& name, | 439 static bool IsPlaneEqual(const std::string& name, |
| 413 const uint8* plane1, uint32 pitch1, | 440 const uint8_t* plane1, |
| 414 const uint8* plane2, uint32 pitch2, | 441 uint32_t pitch1, |
| 415 uint32 width, uint32 height, | 442 const uint8_t* plane2, |
| 443 uint32_t pitch2, |
| 444 uint32_t width, |
| 445 uint32_t height, |
| 416 int max_error) { | 446 int max_error) { |
| 417 const uint8* r1 = plane1; | 447 const uint8_t* r1 = plane1; |
| 418 const uint8* r2 = plane2; | 448 const uint8_t* r2 = plane2; |
| 419 for (uint32 y = 0; y < height; ++y) { | 449 for (uint32_t y = 0; y < height; ++y) { |
| 420 for (uint32 x = 0; x < width; ++x) { | 450 for (uint32_t x = 0; x < width; ++x) { |
| 421 if (abs(static_cast<int>(r1[x] - r2[x])) > max_error) { | 451 if (abs(static_cast<int>(r1[x] - r2[x])) > max_error) { |
| 422 LOG(LS_INFO) << "IsPlaneEqual(" << name << "): pixel[" | 452 LOG(LS_INFO) << "IsPlaneEqual(" << name << "): pixel[" |
| 423 << x << "," << y << "] differs: " | 453 << x << "," << y << "] differs: " |
| 424 << static_cast<int>(r1[x]) << " vs " | 454 << static_cast<int>(r1[x]) << " vs " |
| 425 << static_cast<int>(r2[x]); | 455 << static_cast<int>(r2[x]); |
| 426 return false; | 456 return false; |
| 427 } | 457 } |
| 428 } | 458 } |
| 429 r1 += pitch1; | 459 r1 += pitch1; |
| 430 r2 += pitch2; | 460 r2 += pitch2; |
| 431 } | 461 } |
| 432 return true; | 462 return true; |
| 433 } | 463 } |
| 434 | 464 |
| 435 static bool IsEqual(const cricket::VideoFrame& frame, | 465 static bool IsEqual(const cricket::VideoFrame& frame, |
| 436 size_t width, size_t height, | 466 size_t width, |
| 437 size_t pixel_width, size_t pixel_height, | 467 size_t height, |
| 438 int64 time_stamp, | 468 size_t pixel_width, |
| 439 const uint8* y, uint32 ypitch, | 469 size_t pixel_height, |
| 440 const uint8* u, uint32 upitch, | 470 int64_t time_stamp, |
| 441 const uint8* v, uint32 vpitch, | 471 const uint8_t* y, |
| 472 uint32_t ypitch, |
| 473 const uint8_t* u, |
| 474 uint32_t upitch, |
| 475 const uint8_t* v, |
| 476 uint32_t vpitch, |
| 442 int max_error) { | 477 int max_error) { |
| 443 return IsSize(frame, | 478 return IsSize(frame, static_cast<uint32_t>(width), |
| 444 static_cast<uint32>(width), | 479 static_cast<uint32_t>(height)) && |
| 445 static_cast<uint32>(height)) && | 480 frame.GetPixelWidth() == pixel_width && |
| 446 frame.GetPixelWidth() == pixel_width && | 481 frame.GetPixelHeight() == pixel_height && |
| 447 frame.GetPixelHeight() == pixel_height && | 482 frame.GetTimeStamp() == time_stamp && |
| 448 frame.GetTimeStamp() == time_stamp && | 483 IsPlaneEqual("y", frame.GetYPlane(), frame.GetYPitch(), y, ypitch, |
| 449 IsPlaneEqual("y", frame.GetYPlane(), frame.GetYPitch(), y, ypitch, | 484 static_cast<uint32_t>(width), |
| 450 static_cast<uint32>(width), | 485 static_cast<uint32_t>(height), max_error) && |
| 451 static_cast<uint32>(height), max_error) && | 486 IsPlaneEqual("u", frame.GetUPlane(), frame.GetUPitch(), u, upitch, |
| 452 IsPlaneEqual("u", frame.GetUPlane(), frame.GetUPitch(), u, upitch, | 487 static_cast<uint32_t>((width + 1) / 2), |
| 453 static_cast<uint32>((width + 1) / 2), | 488 static_cast<uint32_t>((height + 1) / 2), max_error) && |
| 454 static_cast<uint32>((height + 1) / 2), max_error) && | 489 IsPlaneEqual("v", frame.GetVPlane(), frame.GetVPitch(), v, vpitch, |
| 455 IsPlaneEqual("v", frame.GetVPlane(), frame.GetVPitch(), v, vpitch, | 490 static_cast<uint32_t>((width + 1) / 2), |
| 456 static_cast<uint32>((width + 1) / 2), | 491 static_cast<uint32_t>((height + 1) / 2), max_error); |
| 457 static_cast<uint32>((height + 1) / 2), max_error); | |
| 458 } | 492 } |
| 459 | 493 |
| 460 static bool IsEqual(const cricket::VideoFrame& frame1, | 494 static bool IsEqual(const cricket::VideoFrame& frame1, |
| 461 const cricket::VideoFrame& frame2, | 495 const cricket::VideoFrame& frame2, |
| 462 int max_error) { | 496 int max_error) { |
| 463 return IsEqual(frame1, | 497 return IsEqual(frame1, |
| 464 frame2.GetWidth(), frame2.GetHeight(), | 498 frame2.GetWidth(), frame2.GetHeight(), |
| 465 frame2.GetPixelWidth(), frame2.GetPixelHeight(), | 499 frame2.GetPixelWidth(), frame2.GetPixelHeight(), |
| 466 frame2.GetTimeStamp(), | 500 frame2.GetTimeStamp(), |
| 467 frame2.GetYPlane(), frame2.GetYPitch(), | 501 frame2.GetYPlane(), frame2.GetYPitch(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 | 539 |
| 506 // Test constructing an image from a I420 buffer. | 540 // Test constructing an image from a I420 buffer. |
| 507 void ConstructI420() { | 541 void ConstructI420() { |
| 508 T frame; | 542 T frame; |
| 509 EXPECT_TRUE(IsNull(frame)); | 543 EXPECT_TRUE(IsNull(frame)); |
| 510 rtc::scoped_ptr<rtc::MemoryStream> ms( | 544 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 511 CreateYuvSample(kWidth, kHeight, 12)); | 545 CreateYuvSample(kWidth, kHeight, 12)); |
| 512 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, | 546 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, |
| 513 kWidth, kHeight, &frame)); | 547 kWidth, kHeight, &frame)); |
| 514 | 548 |
| 515 const uint8* y = reinterpret_cast<uint8*>(ms.get()->GetBuffer()); | 549 const uint8_t* y = reinterpret_cast<uint8_t*>(ms.get()->GetBuffer()); |
| 516 const uint8* u = y + kWidth * kHeight; | 550 const uint8_t* u = y + kWidth * kHeight; |
| 517 const uint8* v = u + kWidth * kHeight / 4; | 551 const uint8_t* v = u + kWidth * kHeight / 4; |
| 518 EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, | 552 EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, y, kWidth, u, |
| 519 y, kWidth, u, kWidth / 2, v, kWidth / 2, 0)); | 553 kWidth / 2, v, kWidth / 2, 0)); |
| 520 } | 554 } |
| 521 | 555 |
| 522 // Test constructing an image from a YV12 buffer. | 556 // Test constructing an image from a YV12 buffer. |
| 523 void ConstructYV12() { | 557 void ConstructYV12() { |
| 524 T frame; | 558 T frame; |
| 525 rtc::scoped_ptr<rtc::MemoryStream> ms( | 559 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 526 CreateYuvSample(kWidth, kHeight, 12)); | 560 CreateYuvSample(kWidth, kHeight, 12)); |
| 527 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YV12, | 561 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YV12, |
| 528 kWidth, kHeight, &frame)); | 562 kWidth, kHeight, &frame)); |
| 529 | 563 |
| 530 const uint8* y = reinterpret_cast<uint8*>(ms.get()->GetBuffer()); | 564 const uint8_t* y = reinterpret_cast<uint8_t*>(ms.get()->GetBuffer()); |
| 531 const uint8* v = y + kWidth * kHeight; | 565 const uint8_t* v = y + kWidth * kHeight; |
| 532 const uint8* u = v + kWidth * kHeight / 4; | 566 const uint8_t* u = v + kWidth * kHeight / 4; |
| 533 EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, | 567 EXPECT_TRUE(IsEqual(frame, kWidth, kHeight, 1, 1, 0, y, kWidth, u, |
| 534 y, kWidth, u, kWidth / 2, v, kWidth / 2, 0)); | 568 kWidth / 2, v, kWidth / 2, 0)); |
| 535 } | 569 } |
| 536 | 570 |
| 537 // Test constructing an image from a I422 buffer. | 571 // Test constructing an image from a I422 buffer. |
| 538 void ConstructI422() { | 572 void ConstructI422() { |
| 539 T frame1, frame2; | 573 T frame1, frame2; |
| 540 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 574 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 541 size_t buf_size = kWidth * kHeight * 2; | 575 size_t buf_size = kWidth * kHeight * 2; |
| 542 rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment]); | 576 rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment]); |
| 543 uint8* y = ALIGNP(buf.get(), kAlignment); | 577 uint8_t* y = ALIGNP(buf.get(), kAlignment); |
| 544 uint8* u = y + kWidth * kHeight; | 578 uint8_t* u = y + kWidth * kHeight; |
| 545 uint8* v = u + (kWidth / 2) * kHeight; | 579 uint8_t* v = u + (kWidth / 2) * kHeight; |
| 546 EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(), | 580 EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(), |
| 547 frame1.GetUPlane(), frame1.GetUPitch(), | 581 frame1.GetUPlane(), frame1.GetUPitch(), |
| 548 frame1.GetVPlane(), frame1.GetVPitch(), | 582 frame1.GetVPlane(), frame1.GetVPitch(), |
| 549 y, kWidth, | 583 y, kWidth, |
| 550 u, kWidth / 2, | 584 u, kWidth / 2, |
| 551 v, kWidth / 2, | 585 v, kWidth / 2, |
| 552 kWidth, kHeight)); | 586 kWidth, kHeight)); |
| 553 EXPECT_TRUE(LoadFrame(y, buf_size, cricket::FOURCC_I422, | 587 EXPECT_TRUE(LoadFrame(y, buf_size, cricket::FOURCC_I422, |
| 554 kWidth, kHeight, &frame2)); | 588 kWidth, kHeight, &frame2)); |
| 555 EXPECT_TRUE(IsEqual(frame1, frame2, 1)); | 589 EXPECT_TRUE(IsEqual(frame1, frame2, 1)); |
| 556 } | 590 } |
| 557 | 591 |
| 558 // Test constructing an image from a YUY2 buffer. | 592 // Test constructing an image from a YUY2 buffer. |
| 559 void ConstructYuy2() { | 593 void ConstructYuy2() { |
| 560 T frame1, frame2; | 594 T frame1, frame2; |
| 561 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 595 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 562 size_t buf_size = kWidth * kHeight * 2; | 596 size_t buf_size = kWidth * kHeight * 2; |
| 563 rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment]); | 597 rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment]); |
| 564 uint8* yuy2 = ALIGNP(buf.get(), kAlignment); | 598 uint8_t* yuy2 = ALIGNP(buf.get(), kAlignment); |
| 565 EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(), | 599 EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(), |
| 566 frame1.GetUPlane(), frame1.GetUPitch(), | 600 frame1.GetUPlane(), frame1.GetUPitch(), |
| 567 frame1.GetVPlane(), frame1.GetVPitch(), | 601 frame1.GetVPlane(), frame1.GetVPitch(), |
| 568 yuy2, kWidth * 2, | 602 yuy2, kWidth * 2, |
| 569 kWidth, kHeight)); | 603 kWidth, kHeight)); |
| 570 EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2, | 604 EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2, |
| 571 kWidth, kHeight, &frame2)); | 605 kWidth, kHeight, &frame2)); |
| 572 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); | 606 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); |
| 573 } | 607 } |
| 574 | 608 |
| 575 // Test constructing an image from a YUY2 buffer with buffer unaligned. | 609 // Test constructing an image from a YUY2 buffer with buffer unaligned. |
| 576 void ConstructYuy2Unaligned() { | 610 void ConstructYuy2Unaligned() { |
| 577 T frame1, frame2; | 611 T frame1, frame2; |
| 578 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 612 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 579 size_t buf_size = kWidth * kHeight * 2; | 613 size_t buf_size = kWidth * kHeight * 2; |
| 580 rtc::scoped_ptr<uint8[]> buf(new uint8[buf_size + kAlignment + 1]); | 614 rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[buf_size + kAlignment + 1]); |
| 581 uint8* yuy2 = ALIGNP(buf.get(), kAlignment) + 1; | 615 uint8_t* yuy2 = ALIGNP(buf.get(), kAlignment) + 1; |
| 582 EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(), | 616 EXPECT_EQ(0, libyuv::I420ToYUY2(frame1.GetYPlane(), frame1.GetYPitch(), |
| 583 frame1.GetUPlane(), frame1.GetUPitch(), | 617 frame1.GetUPlane(), frame1.GetUPitch(), |
| 584 frame1.GetVPlane(), frame1.GetVPitch(), | 618 frame1.GetVPlane(), frame1.GetVPitch(), |
| 585 yuy2, kWidth * 2, | 619 yuy2, kWidth * 2, |
| 586 kWidth, kHeight)); | 620 kWidth, kHeight)); |
| 587 EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2, | 621 EXPECT_TRUE(LoadFrame(yuy2, buf_size, cricket::FOURCC_YUY2, |
| 588 kWidth, kHeight, &frame2)); | 622 kWidth, kHeight, &frame2)); |
| 589 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); | 623 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); |
| 590 } | 624 } |
| 591 | 625 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 &frame1)); | 761 &frame1)); |
| 728 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_RAW, | 762 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_RAW, |
| 729 kWidth, kHeight, &frame2)); | 763 kWidth, kHeight, &frame2)); |
| 730 EXPECT_TRUE(IsEqual(frame1, frame2, 2)); | 764 EXPECT_TRUE(IsEqual(frame1, frame2, 2)); |
| 731 } | 765 } |
| 732 | 766 |
| 733 // Test constructing an image from a RGB565 buffer | 767 // Test constructing an image from a RGB565 buffer |
| 734 void ConstructRGB565() { | 768 void ConstructRGB565() { |
| 735 T frame1, frame2; | 769 T frame1, frame2; |
| 736 size_t out_size = kWidth * kHeight * 2; | 770 size_t out_size = kWidth * kHeight * 2; |
| 737 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]); | 771 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]); |
| 738 uint8* out = ALIGNP(outbuf.get(), kAlignment); | 772 uint8_t* out = ALIGNP(outbuf.get(), kAlignment); |
| 739 T frame; | 773 T frame; |
| 740 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 774 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 741 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBP, | 775 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBP, |
| 742 out, | 776 out, |
| 743 out_size, kWidth * 2)); | 777 out_size, kWidth * 2)); |
| 744 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBP, | 778 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBP, |
| 745 kWidth, kHeight, &frame2)); | 779 kWidth, kHeight, &frame2)); |
| 746 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); | 780 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); |
| 747 } | 781 } |
| 748 | 782 |
| 749 // Test constructing an image from a ARGB1555 buffer | 783 // Test constructing an image from a ARGB1555 buffer |
| 750 void ConstructARGB1555() { | 784 void ConstructARGB1555() { |
| 751 T frame1, frame2; | 785 T frame1, frame2; |
| 752 size_t out_size = kWidth * kHeight * 2; | 786 size_t out_size = kWidth * kHeight * 2; |
| 753 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]); | 787 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]); |
| 754 uint8* out = ALIGNP(outbuf.get(), kAlignment); | 788 uint8_t* out = ALIGNP(outbuf.get(), kAlignment); |
| 755 T frame; | 789 T frame; |
| 756 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 790 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 757 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBO, | 791 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_RGBO, |
| 758 out, | 792 out, |
| 759 out_size, kWidth * 2)); | 793 out_size, kWidth * 2)); |
| 760 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBO, | 794 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_RGBO, |
| 761 kWidth, kHeight, &frame2)); | 795 kWidth, kHeight, &frame2)); |
| 762 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); | 796 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); |
| 763 } | 797 } |
| 764 | 798 |
| 765 // Test constructing an image from a ARGB4444 buffer | 799 // Test constructing an image from a ARGB4444 buffer |
| 766 void ConstructARGB4444() { | 800 void ConstructARGB4444() { |
| 767 T frame1, frame2; | 801 T frame1, frame2; |
| 768 size_t out_size = kWidth * kHeight * 2; | 802 size_t out_size = kWidth * kHeight * 2; |
| 769 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]); | 803 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]); |
| 770 uint8* out = ALIGNP(outbuf.get(), kAlignment); | 804 uint8_t* out = ALIGNP(outbuf.get(), kAlignment); |
| 771 T frame; | 805 T frame; |
| 772 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 806 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 773 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_R444, | 807 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(cricket::FOURCC_R444, |
| 774 out, | 808 out, |
| 775 out_size, kWidth * 2)); | 809 out_size, kWidth * 2)); |
| 776 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_R444, | 810 EXPECT_TRUE(LoadFrame(out, out_size, cricket::FOURCC_R444, |
| 777 kWidth, kHeight, &frame2)); | 811 kWidth, kHeight, &frame2)); |
| 778 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); | 812 EXPECT_TRUE(IsEqual(frame1, frame2, 20)); |
| 779 } | 813 } |
| 780 | 814 |
| 781 // Macro to help test different rotations | 815 // Macro to help test different rotations |
| 782 #define TEST_MIRROR(FOURCC, BPP) \ | 816 #define TEST_MIRROR(FOURCC, BPP) \ |
| 783 void Construct##FOURCC##Mirror() { \ | 817 void Construct##FOURCC##Mirror() { \ |
| 784 T frame1, frame2, frame3; \ | 818 T frame1, frame2, frame3; \ |
| 785 rtc::scoped_ptr<rtc::MemoryStream> ms( \ | 819 rtc::scoped_ptr<rtc::MemoryStream> ms( \ |
| 786 CreateYuvSample(kWidth, kHeight, BPP)); \ | 820 CreateYuvSample(kWidth, kHeight, BPP)); \ |
| 787 ASSERT_TRUE(ms.get() != NULL); \ | 821 ASSERT_TRUE(ms.get() != NULL); \ |
| 788 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth, \ | 822 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth, \ |
| 789 -kHeight, kWidth, kHeight, \ | 823 -kHeight, kWidth, kHeight, \ |
| 790 webrtc::kVideoRotation_180, &frame1)); \ | 824 webrtc::kVideoRotation_180, &frame1)); \ |
| 791 size_t data_size; \ | 825 size_t data_size; \ |
| 792 bool ret = ms->GetSize(&data_size); \ | 826 bool ret = ms->GetSize(&data_size); \ |
| 793 EXPECT_TRUE(ret); \ | 827 EXPECT_TRUE(ret); \ |
| 794 EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \ | 828 EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \ |
| 795 kHeight, \ | 829 kHeight, \ |
| 796 reinterpret_cast<uint8*>(ms->GetBuffer()), \ | 830 reinterpret_cast<uint8_t*>(ms->GetBuffer()), \ |
| 797 data_size, 1, 1, 0, webrtc::kVideoRotation_0)); \ | 831 data_size, 1, 1, 0, webrtc::kVideoRotation_0)); \ |
| 798 int width_rotate = static_cast<int>(frame1.GetWidth()); \ | 832 int width_rotate = static_cast<int>(frame1.GetWidth()); \ |
| 799 int height_rotate = static_cast<int>(frame1.GetHeight()); \ | 833 int height_rotate = static_cast<int>(frame1.GetHeight()); \ |
| 800 EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0)); \ | 834 EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0)); \ |
| 801 libyuv::I420Mirror( \ | 835 libyuv::I420Mirror( \ |
| 802 frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(), \ | 836 frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(), \ |
| 803 frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(), \ | 837 frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(), \ |
| 804 frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(), \ | 838 frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(), \ |
| 805 frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth, \ | 839 frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth, \ |
| 806 kHeight); \ | 840 kHeight); \ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 817 CreateYuvSample(kWidth, kHeight, BPP)); \ | 851 CreateYuvSample(kWidth, kHeight, BPP)); \ |
| 818 ASSERT_TRUE(ms.get() != NULL); \ | 852 ASSERT_TRUE(ms.get() != NULL); \ |
| 819 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth, kHeight, \ | 853 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_##FOURCC, kWidth, kHeight, \ |
| 820 kWidth, kHeight, webrtc::kVideoRotation_##ROTATE, \ | 854 kWidth, kHeight, webrtc::kVideoRotation_##ROTATE, \ |
| 821 &frame1)); \ | 855 &frame1)); \ |
| 822 size_t data_size; \ | 856 size_t data_size; \ |
| 823 bool ret = ms->GetSize(&data_size); \ | 857 bool ret = ms->GetSize(&data_size); \ |
| 824 EXPECT_TRUE(ret); \ | 858 EXPECT_TRUE(ret); \ |
| 825 EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \ | 859 EXPECT_TRUE(frame2.Init(cricket::FOURCC_##FOURCC, kWidth, kHeight, kWidth, \ |
| 826 kHeight, \ | 860 kHeight, \ |
| 827 reinterpret_cast<uint8*>(ms->GetBuffer()), \ | 861 reinterpret_cast<uint8_t*>(ms->GetBuffer()), \ |
| 828 data_size, 1, 1, 0, webrtc::kVideoRotation_0)); \ | 862 data_size, 1, 1, 0, webrtc::kVideoRotation_0)); \ |
| 829 int width_rotate = static_cast<int>(frame1.GetWidth()); \ | 863 int width_rotate = static_cast<int>(frame1.GetWidth()); \ |
| 830 int height_rotate = static_cast<int>(frame1.GetHeight()); \ | 864 int height_rotate = static_cast<int>(frame1.GetHeight()); \ |
| 831 EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0)); \ | 865 EXPECT_TRUE(frame3.InitToBlack(width_rotate, height_rotate, 1, 1, 0)); \ |
| 832 libyuv::I420Rotate( \ | 866 libyuv::I420Rotate( \ |
| 833 frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(), \ | 867 frame2.GetYPlane(), frame2.GetYPitch(), frame2.GetUPlane(), \ |
| 834 frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(), \ | 868 frame2.GetUPitch(), frame2.GetVPlane(), frame2.GetVPitch(), \ |
| 835 frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(), \ | 869 frame3.GetYPlane(), frame3.GetYPitch(), frame3.GetUPlane(), \ |
| 836 frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth, \ | 870 frame3.GetUPitch(), frame3.GetVPlane(), frame3.GetVPitch(), kWidth, \ |
| 837 kHeight, libyuv::kRotate##ROTATE); \ | 871 kHeight, libyuv::kRotate##ROTATE); \ |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight)); | 958 CreateYuv422Sample(cricket::FOURCC_YUY2, kWidth, kHeight)); |
| 925 ASSERT_TRUE(ms.get() != NULL); | 959 ASSERT_TRUE(ms.get() != NULL); |
| 926 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight, | 960 EXPECT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_YUY2, kWidth, kHeight, |
| 927 kWidth, kHeight, webrtc::kVideoRotation_270, | 961 kWidth, kHeight, webrtc::kVideoRotation_270, |
| 928 &frame2)); | 962 &frame2)); |
| 929 } | 963 } |
| 930 | 964 |
| 931 // Test 1 pixel edge case image I420 buffer. | 965 // Test 1 pixel edge case image I420 buffer. |
| 932 void ConstructI4201Pixel() { | 966 void ConstructI4201Pixel() { |
| 933 T frame; | 967 T frame; |
| 934 uint8 pixel[3] = { 1, 2, 3 }; | 968 uint8_t pixel[3] = {1, 2, 3}; |
| 935 for (int i = 0; i < repeat_; ++i) { | 969 for (int i = 0; i < repeat_; ++i) { |
| 936 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel, | 970 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel, |
| 937 sizeof(pixel), 1, 1, 0, webrtc::kVideoRotation_0)); | 971 sizeof(pixel), 1, 1, 0, webrtc::kVideoRotation_0)); |
| 938 } | 972 } |
| 939 const uint8* y = pixel; | 973 const uint8_t* y = pixel; |
| 940 const uint8* u = y + 1; | 974 const uint8_t* u = y + 1; |
| 941 const uint8* v = u + 1; | 975 const uint8_t* v = u + 1; |
| 942 EXPECT_TRUE(IsEqual(frame, 1, 1, 1, 1, 0, | 976 EXPECT_TRUE(IsEqual(frame, 1, 1, 1, 1, 0, y, 1, u, 1, v, 1, 0)); |
| 943 y, 1, u, 1, v, 1, 0)); | |
| 944 } | 977 } |
| 945 | 978 |
| 946 // Test 5 pixel edge case image. | 979 // Test 5 pixel edge case image. |
| 947 void ConstructI4205Pixel() { | 980 void ConstructI4205Pixel() { |
| 948 T frame; | 981 T frame; |
| 949 uint8 pixels5x5[5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) * 2]; | 982 uint8_t pixels5x5[5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) * 2]; |
| 950 memset(pixels5x5, 1, 5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) * 2); | 983 memset(pixels5x5, 1, 5 * 5 + ((5 + 1) / 2 * (5 + 1) / 2) * 2); |
| 951 for (int i = 0; i < repeat_; ++i) { | 984 for (int i = 0; i < repeat_; ++i) { |
| 952 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 5, 5, 5, 5, pixels5x5, | 985 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 5, 5, 5, 5, pixels5x5, |
| 953 sizeof(pixels5x5), 1, 1, 0, | 986 sizeof(pixels5x5), 1, 1, 0, |
| 954 webrtc::kVideoRotation_0)); | 987 webrtc::kVideoRotation_0)); |
| 955 } | 988 } |
| 956 EXPECT_EQ(5u, frame.GetWidth()); | 989 EXPECT_EQ(5u, frame.GetWidth()); |
| 957 EXPECT_EQ(5u, frame.GetHeight()); | 990 EXPECT_EQ(5u, frame.GetHeight()); |
| 958 EXPECT_EQ(5, frame.GetYPitch()); | 991 EXPECT_EQ(5, frame.GetYPitch()); |
| 959 EXPECT_EQ(3, frame.GetUPitch()); | 992 EXPECT_EQ(3, frame.GetUPitch()); |
| 960 EXPECT_EQ(3, frame.GetVPitch()); | 993 EXPECT_EQ(3, frame.GetVPitch()); |
| 961 } | 994 } |
| 962 | 995 |
| 963 // Test 1 pixel edge case image ARGB buffer. | 996 // Test 1 pixel edge case image ARGB buffer. |
| 964 void ConstructARGB1Pixel() { | 997 void ConstructARGB1Pixel() { |
| 965 T frame; | 998 T frame; |
| 966 uint8 pixel[4] = { 64, 128, 192, 255 }; | 999 uint8_t pixel[4] = {64, 128, 192, 255}; |
| 967 for (int i = 0; i < repeat_; ++i) { | 1000 for (int i = 0; i < repeat_; ++i) { |
| 968 EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 1, 1, 1, 1, pixel, | 1001 EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 1, 1, 1, 1, pixel, |
| 969 sizeof(pixel), 1, 1, 0, | 1002 sizeof(pixel), 1, 1, 0, |
| 970 webrtc::kVideoRotation_0)); | 1003 webrtc::kVideoRotation_0)); |
| 971 } | 1004 } |
| 972 // Convert back to ARGB. | 1005 // Convert back to ARGB. |
| 973 size_t out_size = 4; | 1006 size_t out_size = 4; |
| 974 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]); | 1007 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]); |
| 975 uint8* out = ALIGNP(outbuf.get(), kAlignment); | 1008 uint8_t* out = ALIGNP(outbuf.get(), kAlignment); |
| 976 | 1009 |
| 977 EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB, | 1010 EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB, |
| 978 out, | 1011 out, |
| 979 out_size, // buffer size | 1012 out_size, // buffer size |
| 980 out_size)); // stride | 1013 out_size)); // stride |
| 981 #ifdef USE_LMI_CONVERT | 1014 #ifdef USE_LMI_CONVERT |
| 982 // TODO(fbarchard): Expected to fail, but not crash. | 1015 // TODO(fbarchard): Expected to fail, but not crash. |
| 983 EXPECT_FALSE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2)); | 1016 EXPECT_FALSE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2)); |
| 984 #else | 1017 #else |
| 985 // TODO(fbarchard): Check for overwrite. | 1018 // TODO(fbarchard): Check for overwrite. |
| 986 EXPECT_TRUE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2)); | 1019 EXPECT_TRUE(IsPlaneEqual("argb", pixel, 4, out, 4, 3, 1, 2)); |
| 987 #endif | 1020 #endif |
| 988 } | 1021 } |
| 989 | 1022 |
| 990 // Test Black, White and Grey pixels. | 1023 // Test Black, White and Grey pixels. |
| 991 void ConstructARGBBlackWhitePixel() { | 1024 void ConstructARGBBlackWhitePixel() { |
| 992 T frame; | 1025 T frame; |
| 993 uint8 pixel[10 * 4] = { 0, 0, 0, 255, // Black. | 1026 uint8_t pixel[10 * 4] = {0, 0, 0, 255, // Black. |
| 994 0, 0, 0, 255, | 1027 0, 0, 0, 255, // Black. |
| 995 64, 64, 64, 255, // Dark Grey. | 1028 64, 64, 64, 255, // Dark Grey. |
| 996 64, 64, 64, 255, | 1029 64, 64, 64, 255, // Dark Grey. |
| 997 128, 128, 128, 255, // Grey. | 1030 128, 128, 128, 255, // Grey. |
| 998 128, 128, 128, 255, | 1031 128, 128, 128, 255, // Grey. |
| 999 196, 196, 196, 255, // Light Grey. | 1032 196, 196, 196, 255, // Light Grey. |
| 1000 196, 196, 196, 255, | 1033 196, 196, 196, 255, // Light Grey. |
| 1001 255, 255, 255, 255, // White. | 1034 255, 255, 255, 255, // White. |
| 1002 255, 255, 255, 255 }; | 1035 255, 255, 255, 255}; // White. |
| 1003 | 1036 |
| 1004 for (int i = 0; i < repeat_; ++i) { | 1037 for (int i = 0; i < repeat_; ++i) { |
| 1005 EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 10, 1, 10, 1, pixel, | 1038 EXPECT_TRUE(frame.Init(cricket::FOURCC_ARGB, 10, 1, 10, 1, pixel, |
| 1006 sizeof(pixel), 1, 1, 0, | 1039 sizeof(pixel), 1, 1, 0, |
| 1007 webrtc::kVideoRotation_0)); | 1040 webrtc::kVideoRotation_0)); |
| 1008 } | 1041 } |
| 1009 // Convert back to ARGB | 1042 // Convert back to ARGB |
| 1010 size_t out_size = 10 * 4; | 1043 size_t out_size = 10 * 4; |
| 1011 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment]); | 1044 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment]); |
| 1012 uint8* out = ALIGNP(outbuf.get(), kAlignment); | 1045 uint8_t* out = ALIGNP(outbuf.get(), kAlignment); |
| 1013 | 1046 |
| 1014 EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB, | 1047 EXPECT_EQ(out_size, frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB, |
| 1015 out, | 1048 out, |
| 1016 out_size, // buffer size. | 1049 out_size, // buffer size. |
| 1017 out_size)); // stride. | 1050 out_size)); // stride. |
| 1018 EXPECT_TRUE(IsPlaneEqual("argb", pixel, out_size, | 1051 EXPECT_TRUE(IsPlaneEqual("argb", pixel, out_size, |
| 1019 out, out_size, | 1052 out, out_size, |
| 1020 out_size, 1, 2)); | 1053 out_size, 1, 2)); |
| 1021 } | 1054 } |
| 1022 | 1055 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 1157 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 1125 ASSERT_TRUE(LoadFrame(kJpeg400Filename, | 1158 ASSERT_TRUE(LoadFrame(kJpeg400Filename, |
| 1126 cricket::FOURCC_MJPG, kWidth, kHeight, &frame2)); | 1159 cricket::FOURCC_MJPG, kWidth, kHeight, &frame2)); |
| 1127 EXPECT_TRUE(IsPlaneEqual("y", frame1.GetYPlane(), frame1.GetYPitch(), | 1160 EXPECT_TRUE(IsPlaneEqual("y", frame1.GetYPlane(), frame1.GetYPitch(), |
| 1128 frame2.GetYPlane(), frame2.GetYPitch(), | 1161 frame2.GetYPlane(), frame2.GetYPitch(), |
| 1129 kWidth, kHeight, 32)); | 1162 kWidth, kHeight, 32)); |
| 1130 EXPECT_TRUE(IsEqual(frame1, frame2, 128)); | 1163 EXPECT_TRUE(IsEqual(frame1, frame2, 128)); |
| 1131 } | 1164 } |
| 1132 | 1165 |
| 1133 // Test constructing an image from an I420 MJPG buffer. | 1166 // Test constructing an image from an I420 MJPG buffer. |
| 1134 void ValidateFrame(const char* name, uint32 fourcc, int data_adjust, | 1167 void ValidateFrame(const char* name, |
| 1135 int size_adjust, bool expected_result) { | 1168 uint32_t fourcc, |
| 1169 int data_adjust, |
| 1170 int size_adjust, |
| 1171 bool expected_result) { |
| 1136 T frame; | 1172 T frame; |
| 1137 rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(name)); | 1173 rtc::scoped_ptr<rtc::MemoryStream> ms(LoadSample(name)); |
| 1138 ASSERT_TRUE(ms.get() != NULL); | 1174 ASSERT_TRUE(ms.get() != NULL); |
| 1139 const uint8* sample = reinterpret_cast<const uint8*>(ms.get()->GetBuffer()); | 1175 const uint8_t* sample = |
| 1176 reinterpret_cast<const uint8_t*>(ms.get()->GetBuffer()); |
| 1140 size_t sample_size; | 1177 size_t sample_size; |
| 1141 ms->GetSize(&sample_size); | 1178 ms->GetSize(&sample_size); |
| 1142 // Optional adjust size to test invalid size. | 1179 // Optional adjust size to test invalid size. |
| 1143 size_t data_size = sample_size + data_adjust; | 1180 size_t data_size = sample_size + data_adjust; |
| 1144 | 1181 |
| 1145 // Allocate a buffer with end page aligned. | 1182 // Allocate a buffer with end page aligned. |
| 1146 const int kPadToHeapSized = 16 * 1024 * 1024; | 1183 const int kPadToHeapSized = 16 * 1024 * 1024; |
| 1147 rtc::scoped_ptr<uint8[]> page_buffer( | 1184 rtc::scoped_ptr<uint8_t[]> page_buffer( |
| 1148 new uint8[((data_size + kPadToHeapSized + 4095) & ~4095)]); | 1185 new uint8_t[((data_size + kPadToHeapSized + 4095) & ~4095)]); |
| 1149 uint8* data_ptr = page_buffer.get(); | 1186 uint8_t* data_ptr = page_buffer.get(); |
| 1150 if (!data_ptr) { | 1187 if (!data_ptr) { |
| 1151 LOG(LS_WARNING) << "Failed to allocate memory for ValidateFrame test."; | 1188 LOG(LS_WARNING) << "Failed to allocate memory for ValidateFrame test."; |
| 1152 EXPECT_FALSE(expected_result); // NULL is okay if failure was expected. | 1189 EXPECT_FALSE(expected_result); // NULL is okay if failure was expected. |
| 1153 return; | 1190 return; |
| 1154 } | 1191 } |
| 1155 data_ptr += kPadToHeapSized + (-(static_cast<int>(data_size)) & 4095); | 1192 data_ptr += kPadToHeapSized + (-(static_cast<int>(data_size)) & 4095); |
| 1156 memcpy(data_ptr, sample, std::min(data_size, sample_size)); | 1193 memcpy(data_ptr, sample, std::min(data_size, sample_size)); |
| 1157 for (int i = 0; i < repeat_; ++i) { | 1194 for (int i = 0; i < repeat_; ++i) { |
| 1158 EXPECT_EQ(expected_result, frame.Validate(fourcc, kWidth, kHeight, | 1195 EXPECT_EQ(expected_result, frame.Validate(fourcc, kWidth, kHeight, |
| 1159 data_ptr, | 1196 data_ptr, |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 rtc::scoped_ptr<rtc::MemoryStream> ms( | 1413 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 1377 LoadSample(kImageFilename)); | 1414 LoadSample(kImageFilename)); |
| 1378 ASSERT_TRUE(ms.get() != NULL); | 1415 ASSERT_TRUE(ms.get() != NULL); |
| 1379 size_t data_size; | 1416 size_t data_size; |
| 1380 ms->GetSize(&data_size); | 1417 ms->GetSize(&data_size); |
| 1381 EXPECT_TRUE(frame1.InitToBlack(kWidth, kHeight, 1, 1, 0)); | 1418 EXPECT_TRUE(frame1.InitToBlack(kWidth, kHeight, 1, 1, 0)); |
| 1382 EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0)); | 1419 EXPECT_TRUE(frame2.InitToBlack(kWidth, kHeight, 1, 1, 0)); |
| 1383 EXPECT_TRUE(IsBlack(frame1)); | 1420 EXPECT_TRUE(IsBlack(frame1)); |
| 1384 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); | 1421 EXPECT_TRUE(IsEqual(frame1, frame2, 0)); |
| 1385 EXPECT_TRUE(frame1.Reset(cricket::FOURCC_I420, kWidth, kHeight, kWidth, | 1422 EXPECT_TRUE(frame1.Reset(cricket::FOURCC_I420, kWidth, kHeight, kWidth, |
| 1386 kHeight, reinterpret_cast<uint8*>(ms->GetBuffer()), | 1423 kHeight, |
| 1387 data_size, 1, 1, 0, rotation, | 1424 reinterpret_cast<uint8_t*>(ms->GetBuffer()), |
| 1388 apply_rotation)); | 1425 data_size, 1, 1, 0, rotation, apply_rotation)); |
| 1389 if (apply_rotation) | 1426 if (apply_rotation) |
| 1390 EXPECT_EQ(webrtc::kVideoRotation_0, frame1.GetVideoRotation()); | 1427 EXPECT_EQ(webrtc::kVideoRotation_0, frame1.GetVideoRotation()); |
| 1391 else | 1428 else |
| 1392 EXPECT_EQ(rotation, frame1.GetVideoRotation()); | 1429 EXPECT_EQ(rotation, frame1.GetVideoRotation()); |
| 1393 | 1430 |
| 1394 // Swapp width and height if the frame is rotated 90 or 270 degrees. | 1431 // Swapp width and height if the frame is rotated 90 or 270 degrees. |
| 1395 if (apply_rotation && (rotation == webrtc::kVideoRotation_90 | 1432 if (apply_rotation && (rotation == webrtc::kVideoRotation_90 |
| 1396 || rotation == webrtc::kVideoRotation_270)) { | 1433 || rotation == webrtc::kVideoRotation_270)) { |
| 1397 EXPECT_TRUE(kHeight == frame1.GetWidth()); | 1434 EXPECT_TRUE(kHeight == frame1.GetWidth()); |
| 1398 EXPECT_TRUE(kWidth == frame1.GetHeight()); | 1435 EXPECT_TRUE(kWidth == frame1.GetHeight()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1412 Reset(webrtc::kVideoRotation_90, false); | 1449 Reset(webrtc::kVideoRotation_90, false); |
| 1413 } | 1450 } |
| 1414 | 1451 |
| 1415 ////////////////////// | 1452 ////////////////////// |
| 1416 // Conversion tests // | 1453 // Conversion tests // |
| 1417 ////////////////////// | 1454 ////////////////////// |
| 1418 | 1455 |
| 1419 enum ToFrom { TO, FROM }; | 1456 enum ToFrom { TO, FROM }; |
| 1420 | 1457 |
| 1421 // Helper function for test converting from I420 to packed formats. | 1458 // Helper function for test converting from I420 to packed formats. |
| 1422 inline void ConvertToBuffer(int bpp, int rowpad, bool invert, ToFrom to_from, | 1459 inline void ConvertToBuffer(int bpp, |
| 1423 int error, uint32 fourcc, | 1460 int rowpad, |
| 1424 int (*RGBToI420)(const uint8* src_frame, int src_stride_frame, | 1461 bool invert, |
| 1425 uint8* dst_y, int dst_stride_y, | 1462 ToFrom to_from, |
| 1426 uint8* dst_u, int dst_stride_u, | 1463 int error, |
| 1427 uint8* dst_v, int dst_stride_v, | 1464 uint32_t fourcc, |
| 1428 int width, int height)) { | 1465 int (*RGBToI420)(const uint8_t* src_frame, |
| 1466 int src_stride_frame, |
| 1467 uint8_t* dst_y, |
| 1468 int dst_stride_y, |
| 1469 uint8_t* dst_u, |
| 1470 int dst_stride_u, |
| 1471 uint8_t* dst_v, |
| 1472 int dst_stride_v, |
| 1473 int width, |
| 1474 int height)) { |
| 1429 T frame1, frame2; | 1475 T frame1, frame2; |
| 1430 int repeat_to = (to_from == TO) ? repeat_ : 1; | 1476 int repeat_to = (to_from == TO) ? repeat_ : 1; |
| 1431 int repeat_from = (to_from == FROM) ? repeat_ : 1; | 1477 int repeat_from = (to_from == FROM) ? repeat_ : 1; |
| 1432 | 1478 |
| 1433 int astride = kWidth * bpp + rowpad; | 1479 int astride = kWidth * bpp + rowpad; |
| 1434 size_t out_size = astride * kHeight; | 1480 size_t out_size = astride * kHeight; |
| 1435 rtc::scoped_ptr<uint8[]> outbuf(new uint8[out_size + kAlignment + 1]); | 1481 rtc::scoped_ptr<uint8_t[]> outbuf(new uint8_t[out_size + kAlignment + 1]); |
| 1436 memset(outbuf.get(), 0, out_size + kAlignment + 1); | 1482 memset(outbuf.get(), 0, out_size + kAlignment + 1); |
| 1437 uint8* outtop = ALIGNP(outbuf.get(), kAlignment); | 1483 uint8_t* outtop = ALIGNP(outbuf.get(), kAlignment); |
| 1438 uint8* out = outtop; | 1484 uint8_t* out = outtop; |
| 1439 int stride = astride; | 1485 int stride = astride; |
| 1440 if (invert) { | 1486 if (invert) { |
| 1441 out += (kHeight - 1) * stride; // Point to last row. | 1487 out += (kHeight - 1) * stride; // Point to last row. |
| 1442 stride = -stride; | 1488 stride = -stride; |
| 1443 } | 1489 } |
| 1444 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 1490 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 1445 | 1491 |
| 1446 for (int i = 0; i < repeat_to; ++i) { | 1492 for (int i = 0; i < repeat_to; ++i) { |
| 1447 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(fourcc, | 1493 EXPECT_EQ(out_size, frame1.ConvertToRgbBuffer(fourcc, |
| 1448 out, | 1494 out, |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1743 } | 1789 } |
| 1744 void ConvertFromUYVYBufferInverted() { | 1790 void ConvertFromUYVYBufferInverted() { |
| 1745 ConvertToBuffer(2, 0, true, FROM, kError, | 1791 ConvertToBuffer(2, 0, true, FROM, kError, |
| 1746 cricket::FOURCC_UYVY, libyuv::UYVYToI420); | 1792 cricket::FOURCC_UYVY, libyuv::UYVYToI420); |
| 1747 } | 1793 } |
| 1748 | 1794 |
| 1749 // Test converting from I420 to I422. | 1795 // Test converting from I420 to I422. |
| 1750 void ConvertToI422Buffer() { | 1796 void ConvertToI422Buffer() { |
| 1751 T frame1, frame2; | 1797 T frame1, frame2; |
| 1752 size_t out_size = kWidth * kHeight * 2; | 1798 size_t out_size = kWidth * kHeight * 2; |
| 1753 rtc::scoped_ptr<uint8[]> buf(new uint8[out_size + kAlignment]); | 1799 rtc::scoped_ptr<uint8_t[]> buf(new uint8_t[out_size + kAlignment]); |
| 1754 uint8* y = ALIGNP(buf.get(), kAlignment); | 1800 uint8_t* y = ALIGNP(buf.get(), kAlignment); |
| 1755 uint8* u = y + kWidth * kHeight; | 1801 uint8_t* u = y + kWidth * kHeight; |
| 1756 uint8* v = u + (kWidth / 2) * kHeight; | 1802 uint8_t* v = u + (kWidth / 2) * kHeight; |
| 1757 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); | 1803 ASSERT_TRUE(LoadFrameNoRepeat(&frame1)); |
| 1758 for (int i = 0; i < repeat_; ++i) { | 1804 for (int i = 0; i < repeat_; ++i) { |
| 1759 EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(), | 1805 EXPECT_EQ(0, libyuv::I420ToI422(frame1.GetYPlane(), frame1.GetYPitch(), |
| 1760 frame1.GetUPlane(), frame1.GetUPitch(), | 1806 frame1.GetUPlane(), frame1.GetUPitch(), |
| 1761 frame1.GetVPlane(), frame1.GetVPitch(), | 1807 frame1.GetVPlane(), frame1.GetVPitch(), |
| 1762 y, kWidth, | 1808 y, kWidth, |
| 1763 u, kWidth / 2, | 1809 u, kWidth / 2, |
| 1764 v, kWidth / 2, | 1810 v, kWidth / 2, |
| 1765 kWidth, kHeight)); | 1811 kWidth, kHeight)); |
| 1766 } | 1812 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 } | 1855 } |
| 1810 | 1856 |
| 1811 void CopyToBuffer() { | 1857 void CopyToBuffer() { |
| 1812 T frame; | 1858 T frame; |
| 1813 rtc::scoped_ptr<rtc::MemoryStream> ms( | 1859 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 1814 LoadSample(kImageFilename)); | 1860 LoadSample(kImageFilename)); |
| 1815 ASSERT_TRUE(ms.get() != NULL); | 1861 ASSERT_TRUE(ms.get() != NULL); |
| 1816 ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight, | 1862 ASSERT_TRUE(LoadFrame(ms.get(), cricket::FOURCC_I420, kWidth, kHeight, |
| 1817 &frame)); | 1863 &frame)); |
| 1818 size_t out_size = kWidth * kHeight * 3 / 2; | 1864 size_t out_size = kWidth * kHeight * 3 / 2; |
| 1819 rtc::scoped_ptr<uint8[]> out(new uint8[out_size]); | 1865 rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size]); |
| 1820 for (int i = 0; i < repeat_; ++i) { | 1866 for (int i = 0; i < repeat_; ++i) { |
| 1821 EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size)); | 1867 EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size)); |
| 1822 } | 1868 } |
| 1823 EXPECT_EQ(0, memcmp(out.get(), ms->GetBuffer(), out_size)); | 1869 EXPECT_EQ(0, memcmp(out.get(), ms->GetBuffer(), out_size)); |
| 1824 } | 1870 } |
| 1825 | 1871 |
| 1826 void CopyToFrame() { | 1872 void CopyToFrame() { |
| 1827 T source; | 1873 T source; |
| 1828 rtc::scoped_ptr<rtc::MemoryStream> ms( | 1874 rtc::scoped_ptr<rtc::MemoryStream> ms( |
| 1829 LoadSample(kImageFilename)); | 1875 LoadSample(kImageFilename)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1857 ms2.SetPosition(0u); // Useful when repeat_ > 1. | 1903 ms2.SetPosition(0u); // Useful when repeat_ > 1. |
| 1858 int error; | 1904 int error; |
| 1859 EXPECT_EQ(rtc::SR_SUCCESS, frame.Write(&ms2, &error)); | 1905 EXPECT_EQ(rtc::SR_SUCCESS, frame.Write(&ms2, &error)); |
| 1860 } | 1906 } |
| 1861 size_t out_size = cricket::VideoFrame::SizeOf(kWidth, kHeight); | 1907 size_t out_size = cricket::VideoFrame::SizeOf(kWidth, kHeight); |
| 1862 EXPECT_EQ(0, memcmp(ms2.GetBuffer(), ms->GetBuffer(), out_size)); | 1908 EXPECT_EQ(0, memcmp(ms2.GetBuffer(), ms->GetBuffer(), out_size)); |
| 1863 } | 1909 } |
| 1864 | 1910 |
| 1865 void CopyToBuffer1Pixel() { | 1911 void CopyToBuffer1Pixel() { |
| 1866 size_t out_size = 3; | 1912 size_t out_size = 3; |
| 1867 rtc::scoped_ptr<uint8[]> out(new uint8[out_size + 1]); | 1913 rtc::scoped_ptr<uint8_t[]> out(new uint8_t[out_size + 1]); |
| 1868 memset(out.get(), 0xfb, out_size + 1); // Fill buffer | 1914 memset(out.get(), 0xfb, out_size + 1); // Fill buffer |
| 1869 uint8 pixel[3] = { 1, 2, 3 }; | 1915 uint8_t pixel[3] = {1, 2, 3}; |
| 1870 T frame; | 1916 T frame; |
| 1871 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel, | 1917 EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, 1, 1, 1, 1, pixel, |
| 1872 sizeof(pixel), 1, 1, 0, | 1918 sizeof(pixel), 1, 1, 0, |
| 1873 webrtc::kVideoRotation_0)); | 1919 webrtc::kVideoRotation_0)); |
| 1874 for (int i = 0; i < repeat_; ++i) { | 1920 for (int i = 0; i < repeat_; ++i) { |
| 1875 EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size)); | 1921 EXPECT_EQ(out_size, frame.CopyToBuffer(out.get(), out_size)); |
| 1876 } | 1922 } |
| 1877 EXPECT_EQ(1, out.get()[0]); // Check Y. Should be 1. | 1923 EXPECT_EQ(1, out.get()[0]); // Check Y. Should be 1. |
| 1878 EXPECT_EQ(2, out.get()[1]); // Check U. Should be 2. | 1924 EXPECT_EQ(2, out.get()[1]); // Check U. Should be 2. |
| 1879 EXPECT_EQ(3, out.get()[2]); // Check V. Should be 3. | 1925 EXPECT_EQ(3, out.get()[2]); // Check V. Should be 3. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1900 ASSERT_TRUE(LoadFrameNoRepeat(&target2)); | 1946 ASSERT_TRUE(LoadFrameNoRepeat(&target2)); |
| 1901 source.StretchToFrame(&target2, true, true); | 1947 source.StretchToFrame(&target2, true, true); |
| 1902 EXPECT_TRUE(IsBlack(target2)); | 1948 EXPECT_TRUE(IsBlack(target2)); |
| 1903 EXPECT_EQ(source.GetTimeStamp(), target2.GetTimeStamp()); | 1949 EXPECT_EQ(source.GetTimeStamp(), target2.GetTimeStamp()); |
| 1904 } | 1950 } |
| 1905 | 1951 |
| 1906 int repeat_; | 1952 int repeat_; |
| 1907 }; | 1953 }; |
| 1908 | 1954 |
| 1909 #endif // TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_ | 1955 #endif // TALK_MEDIA_BASE_VIDEOFRAME_UNITTEST_H_ |
| OLD | NEW |