This source file includes following definitions.
- ConvertRGBToY
- ConvertRGBToU
- ConvertRGBToV
- TEST
#include "base/cpu.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/simd/convert_rgb_to_yuv.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
int ConvertRGBToY(const uint8* rgb) {
int y = 25 * rgb[0] + 129 * rgb[1] + 66 * rgb[2];
y = ((y + 128) >> 8) + 16;
return std::max(0, std::min(255, y));
}
int ConvertRGBToU(const uint8* rgb, int size) {
int u = 112 * rgb[0] - 74 * rgb[1] - 38 * rgb[2];
u = ((u + 128) >> 8) + 128;
return std::max(0, std::min(255, u));
}
int ConvertRGBToV(const uint8* rgb, int size) {
int v = -18 * rgb[0] - 94 * rgb[1] + 112 * rgb[2];
v = ((v + 128) >> 8) + 128;
return std::max(0, std::min(255, v));
}
}
#if defined(MEMORY_SANITIZER)
#define MAYBE_SideBySideRGB DISABLED_SideBySideRGB
#else
#define MAYBE_SideBySideRGB SideBySideRGB
#endif
TEST(YUVConvertTest, MAYBE_SideBySideRGB) {
base::CPU cpu;
if (!cpu.has_ssse3())
return;
const int kStep = 8;
const int kWidth = 256 / kStep;
for (int size = 3; size <= 4; ++size) {
scoped_ptr<uint8[]> rgb(new uint8[kWidth * size]);
scoped_ptr<uint8[]> y(new uint8[kWidth]);
scoped_ptr<uint8[]> u(new uint8[kWidth / 2]);
scoped_ptr<uint8[]> v(new uint8[kWidth / 2]);
void (*convert)(const uint8*, uint8*, uint8*, uint8*,
int, int, int, int, int) = NULL;
if (size == 3)
convert = media::ConvertRGB24ToYUV_SSSE3;
else
convert = media::ConvertRGB32ToYUV_SSSE3;
int total_error = 0;
for (int r = 0; r < kWidth; ++r) {
for (int g = 0; g < kWidth; ++g) {
for (int b = 0; b < kWidth; ++b) {
rgb[b * size + 0] = b * kStep;
rgb[b * size + 1] = g * kStep;
rgb[b * size + 2] = r * kStep;
if (size == 4)
rgb[b * size + 3] = 255;
}
convert(rgb.get(), y.get(), u.get(), v.get(), kWidth, 1, kWidth * size,
kWidth, kWidth / 2);
for (int i = 0; i < kWidth; ++i) {
const uint8* p = &rgb[i * size];
int error = ConvertRGBToY(p) - y[i];
total_error += error > 0 ? error : -error;
}
for (int i = 0; i < kWidth / 2; ++i) {
const uint8* p = &rgb[i * 2 * size];
int error = ConvertRGBToU(p, size) - u[i];
total_error += error > 0 ? error : -error;
}
for (int i = 0; i < kWidth / 2; ++i) {
const uint8* p = &rgb[i * 2 * size];
int error = ConvertRGBToV(p, size) - v[i];
total_error += error > 0 ? error : -error;
}
}
}
EXPECT_EQ(0, total_error);
}
}