Commit 43279ffd authored by fbarchard@google.com's avatar fbarchard@google.com

ARGBToI422 which is similar to ARGBToI420

BUG=none
TEST=libyuvTest.ARGBToI422_CvsOPT (836 ms)
Review URL: https://webrtc-codereview.appspot.com/637006

git-svn-id: http://libyuv.googlecode.com/svn/trunk@278 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent e214fe3f
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 276
Version: 277
License: BSD
License File: LICENSE
......
......@@ -173,6 +173,13 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height);
// ARGB little endian (bgra in memory) to I422
int ARGBToI422(const uint8* src_frame, int src_stride_frame,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Draw a rectangle into I420.
int I420Rect(uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
......
......@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 276
#define LIBYUV_VERSION 277
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -432,6 +432,52 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
return 0;
}
// ARGB little endian (bgra in memory) to I422
// same as I420 except UV plane is full height
int ARGBToI422(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
if (height < 0) {
height = -height;
src_argb = src_argb + (height - 1) * src_stride_argb;
src_stride_argb = -src_stride_argb;
}
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
ARGBToYRow_C;
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
#if defined(HAS_ARGBTOYROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
if (width > 16) {
ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
ARGBToYRow = ARGBToYRow_Any_SSSE3;
}
if (IS_ALIGNED(width, 16)) {
ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3;
ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
ARGBToUVRow = ARGBToUVRow_SSSE3;
if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
ARGBToYRow = ARGBToYRow_SSSE3;
}
}
}
}
#endif
for (int y = 0; y < height; ++y) {
ARGBToUVRow(src_argb, 0, dst_u, dst_v, width);
ARGBToYRow(src_argb, dst_y, width);
src_argb += src_stride_argb;
dst_y += dst_stride_y;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
return 0;
}
int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
uint8* dst_argb, int dst_stride_argb,
int width, int height) {
......
......@@ -25,54 +25,55 @@
namespace libyuv {
#define TESTPLANARTOB(FMT_A, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
TEST_F(libyuvTest, ##FMT_A##To##FMT_B##_CvsOPT) { \
const int src_width = 1280; \
const int src_height = 720; \
align_buffer_16(src_y, src_width * src_height); \
align_buffer_16(src_u, src_width / SUBSAMP_X * src_height / SUBSAMP_Y); \
align_buffer_16(src_v, src_width / SUBSAMP_X * src_height / SUBSAMP_Y); \
align_buffer_16(dst_rgb_c, (src_width * BPP_B) * src_height); \
align_buffer_16(dst_rgb_opt, (src_width * BPP_B) * src_height); \
#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
TEST_F(libyuvTest, ##FMT_PLANAR##To##FMT_B##_CvsOPT) { \
const int kWidth = 1280; \
const int kHeight = 720; \
align_buffer_16(src_y, kWidth * kHeight); \
align_buffer_16(src_u, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(src_v, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < src_height; ++i) \
for (int j = 0; j < src_width; ++j) \
src_y[(i * src_width) + j] = (random() & 0xff); \
for (int i = 0; i < src_height / SUBSAMP_X; ++i) \
for (int j = 0; j < src_width / SUBSAMP_Y; ++j) { \
src_u[(i * src_width / SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * src_width / SUBSAMP_X) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth; ++j) \
src_y[(i * kWidth) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight / SUBSAMP_X; ++i) \
for (int j = 0; j < kWidth / SUBSAMP_Y; ++j) { \
src_u[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
src_v[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
} \
MaskCpuFlags(kCpuInitialized); \
##FMT_A##To##FMT_B(src_y, src_width, \
src_u, src_width / SUBSAMP_X, \
src_v, src_width / SUBSAMP_X, \
dst_rgb_c, src_width * BPP_B, \
src_width, src_height); \
##FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_c, kWidth * BPP_B, \
kWidth, kHeight); \
MaskCpuFlags(-1); \
const int runs = 1000; \
for (int i = 0; i < runs; ++i) { \
##FMT_A##To##FMT_B(src_y, src_width, \
src_u, src_width / SUBSAMP_X, \
src_v, src_width / SUBSAMP_X, \
dst_rgb_opt, src_width * BPP_B, \
src_width, src_height); \
##FMT_PLANAR##To##FMT_B(src_y, kWidth, \
src_u, kWidth / SUBSAMP_X, \
src_v, kWidth / SUBSAMP_X, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, kHeight); \
} \
int err = 0; \
for (int i = 0; i < src_height; ++i) { \
for (int j = 0; j < src_width * BPP_B; ++j) { \
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP_B + j]) - \
static_cast<int>(dst_rgb_opt[i * src_width * BPP_B + j]); \
if (abs(diff) > 2) \
err++; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int diff = static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) - \
static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j]); \
if (abs(diff) > 2) { \
++err; \
} \
} \
} \
EXPECT_EQ(err, 0); \
free_aligned_buffer_16(src_y) \
free_aligned_buffer_16(src_u) \
free_aligned_buffer_16(src_v) \
free_aligned_buffer_16(dst_rgb_c) \
free_aligned_buffer_16(dst_rgb_opt) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
TESTPLANARTOB(I420, 2, 2, ARGB, 4)
......@@ -87,41 +88,124 @@ TESTPLANARTOB(I411, 4, 1, ARGB, 4)
TESTPLANARTOB(I422, 2, 1, ARGB, 4)
TESTPLANARTOB(I444, 1, 1, ARGB, 4)
#define TESTATOPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
TEST_F(libyuvTest, ##FMT_A##To##FMT_PLANAR##_CvsOPT) { \
const int kWidth = 1280; \
const int kHeight = 720; \
align_buffer_16(src_argb, (kWidth * BPP_A) * kHeight); \
align_buffer_16(dst_y_c, kWidth * kHeight); \
align_buffer_16(dst_u_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_c, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_y_opt, kWidth * kHeight); \
align_buffer_16(dst_u_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
align_buffer_16(dst_v_opt, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
srandom(time(NULL)); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth * BPP_A; ++j) \
src_argb[(i * kWidth * BPP_A) + j] = (random() & 0xff); \
MaskCpuFlags(kCpuInitialized); \
##FMT_A##To##FMT_PLANAR(src_argb, kWidth * BPP_A, \
dst_y_c, kWidth, \
dst_u_c, kWidth / SUBSAMP_X, \
dst_v_c, kWidth / SUBSAMP_X, \
kWidth, kHeight); \
MaskCpuFlags(-1); \
const int runs = 1000; \
for (int i = 0; i < runs; ++i) { \
##FMT_A##To##FMT_PLANAR(src_argb, kWidth * BPP_A, \
dst_y_opt, kWidth, \
dst_u_opt, kWidth / SUBSAMP_X, \
dst_v_opt, kWidth / SUBSAMP_X, \
kWidth, kHeight); \
} \
int err = 0; \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth; ++j) { \
int diff = static_cast<int>(dst_y_c[i * kWidth + j]) - \
static_cast<int>(dst_y_opt[i * kWidth + j]); \
if (abs(diff) > 2) { \
++err; \
} \
} \
} \
EXPECT_EQ(err, 0); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int diff = static_cast<int>(dst_u_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_u_opt[i * kWidth / SUBSAMP_X + j]); \
if (abs(diff) > 2) { \
++err; \
} \
} \
} \
EXPECT_EQ(err, 0); \
for (int i = 0; i < kHeight / SUBSAMP_Y; ++i) { \
for (int j = 0; j < kWidth / SUBSAMP_X; ++j) { \
int diff = static_cast<int>(dst_v_c[i * kWidth / SUBSAMP_X + j]) - \
static_cast<int>(dst_v_opt[i * kWidth / SUBSAMP_X + j]); \
if (abs(diff) > 2) { \
++err; \
} \
} \
} \
EXPECT_EQ(err, 0); \
free_aligned_buffer_16(dst_y_c) \
free_aligned_buffer_16(dst_u_c) \
free_aligned_buffer_16(dst_v_c) \
free_aligned_buffer_16(dst_y_opt) \
free_aligned_buffer_16(dst_u_opt) \
free_aligned_buffer_16(dst_v_opt) \
free_aligned_buffer_16(src_argb) \
}
TESTATOPLANAR(ARGB, 4, I420, 2, 2)
TESTATOPLANAR(BGRA, 4, I420, 2, 2)
TESTATOPLANAR(ABGR, 4, I420, 2, 2)
TESTATOPLANAR(RAW, 3, I420, 2, 2)
TESTATOPLANAR(RGB24, 3, I420, 2, 2)
TESTATOPLANAR(RGB565, 2, I420, 2, 2)
TESTATOPLANAR(ARGB1555, 2, I420, 2, 2)
TESTATOPLANAR(ARGB4444, 2, I420, 2, 2)
//TESTATOPLANAR(ARGB, 4, I411, 4, 1)
TESTATOPLANAR(ARGB, 4, I422, 2, 1)
//TESTATOPLANAR(ARGB, 4, I444, 1, 1)
// TODO(fbarchard): Implement and test 411 and 444
#define TESTATOB(FMT_A, BPP_A, FMT_B, BPP_B) \
TEST_F(libyuvTest, ##FMT_A##To##FMT_B##_CvsOPT) { \
const int src_width = 1280; \
const int src_height = 720; \
align_buffer_16(src_argb, src_width * src_height * BPP_A); \
align_buffer_16(dst_rgb_c, (src_width * BPP_B) * src_height); \
align_buffer_16(dst_rgb_opt, (src_width * BPP_B) * src_height); \
const int kWidth = 1280; \
const int kHeight = 720; \
align_buffer_16(src_argb, kWidth * kHeight * BPP_A); \
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
srandom(time(NULL)); \
for (int i = 0; i < src_height; ++i) \
for (int j = 0; j < src_width * BPP_A; ++j) \
src_argb[(i * src_width * BPP_A) + j] = (random() & 0xff); \
for (int i = 0; i < kHeight; ++i) \
for (int j = 0; j < kWidth * BPP_A; ++j) \
src_argb[(i * kWidth * BPP_A) + j] = (random() & 0xff); \
MaskCpuFlags(kCpuInitialized); \
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
dst_rgb_c, src_width * BPP_B, \
src_width, src_height); \
##FMT_A##To##FMT_B(src_argb, kWidth * BPP_A, \
dst_argb_c, kWidth * BPP_B, \
kWidth, kHeight); \
MaskCpuFlags(-1); \
const int runs = 1000; \
for (int i = 0; i < runs; ++i) { \
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
dst_rgb_opt, src_width * BPP_B, \
src_width, src_height); \
##FMT_A##To##FMT_B(src_argb, kWidth * BPP_A, \
dst_argb_opt, kWidth * BPP_B, \
kWidth, kHeight); \
} \
int err = 0; \
for (int i = 0; i < src_height; ++i) { \
for (int j = 0; j < src_width * BPP_B; ++j) { \
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP_B + j]) - \
static_cast<int>(dst_rgb_opt[i * src_width * BPP_B + j]); \
for (int i = 0; i < kHeight; ++i) { \
for (int j = 0; j < kWidth * BPP_B; ++j) { \
int diff = static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) - \
static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j]); \
if (abs(diff) > 2) \
err++; \
} \
} \
EXPECT_EQ(err, 0); \
free_aligned_buffer_16(src_argb) \
free_aligned_buffer_16(dst_rgb_c) \
free_aligned_buffer_16(dst_rgb_opt) \
free_aligned_buffer_16(dst_argb_c) \
free_aligned_buffer_16(dst_argb_opt) \
}
TESTATOB(ARGB, 4, ARGB, 4)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment