mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 01:06:46 +08:00
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
This commit is contained in:
parent
e214fe3f07
commit
43279ffda0
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 276
|
Version: 277
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -173,6 +173,13 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
|||||||
uint8* dst_y, int dst_stride_y,
|
uint8* dst_y, int dst_stride_y,
|
||||||
int width, int height);
|
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.
|
// Draw a rectangle into I420.
|
||||||
int I420Rect(uint8* dst_y, int dst_stride_y,
|
int I420Rect(uint8* dst_y, int dst_stride_y,
|
||||||
uint8* dst_u, int dst_stride_u,
|
uint8* dst_u, int dst_stride_u,
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 276
|
#define LIBYUV_VERSION 277
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
|
|||||||
@ -432,6 +432,52 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
|||||||
return 0;
|
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,
|
int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
|
||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
|||||||
@ -25,54 +25,55 @@
|
|||||||
|
|
||||||
namespace libyuv {
|
namespace libyuv {
|
||||||
|
|
||||||
#define TESTPLANARTOB(FMT_A, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
|
#define TESTPLANARTOB(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B) \
|
||||||
TEST_F(libyuvTest, ##FMT_A##To##FMT_B##_CvsOPT) { \
|
TEST_F(libyuvTest, ##FMT_PLANAR##To##FMT_B##_CvsOPT) { \
|
||||||
const int src_width = 1280; \
|
const int kWidth = 1280; \
|
||||||
const int src_height = 720; \
|
const int kHeight = 720; \
|
||||||
align_buffer_16(src_y, src_width * src_height); \
|
align_buffer_16(src_y, kWidth * kHeight); \
|
||||||
align_buffer_16(src_u, src_width / SUBSAMP_X * src_height / SUBSAMP_Y); \
|
align_buffer_16(src_u, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
|
||||||
align_buffer_16(src_v, src_width / SUBSAMP_X * src_height / SUBSAMP_Y); \
|
align_buffer_16(src_v, kWidth / SUBSAMP_X * kHeight / SUBSAMP_Y); \
|
||||||
align_buffer_16(dst_rgb_c, (src_width * BPP_B) * src_height); \
|
align_buffer_16(dst_argb_c, (kWidth * BPP_B) * kHeight); \
|
||||||
align_buffer_16(dst_rgb_opt, (src_width * BPP_B) * src_height); \
|
align_buffer_16(dst_argb_opt, (kWidth * BPP_B) * kHeight); \
|
||||||
srandom(time(NULL)); \
|
srandom(time(NULL)); \
|
||||||
for (int i = 0; i < src_height; ++i) \
|
for (int i = 0; i < kHeight; ++i) \
|
||||||
for (int j = 0; j < src_width; ++j) \
|
for (int j = 0; j < kWidth; ++j) \
|
||||||
src_y[(i * src_width) + j] = (random() & 0xff); \
|
src_y[(i * kWidth) + j] = (random() & 0xff); \
|
||||||
for (int i = 0; i < src_height / SUBSAMP_X; ++i) \
|
for (int i = 0; i < kHeight / SUBSAMP_X; ++i) \
|
||||||
for (int j = 0; j < src_width / SUBSAMP_Y; ++j) { \
|
for (int j = 0; j < kWidth / SUBSAMP_Y; ++j) { \
|
||||||
src_u[(i * src_width / SUBSAMP_X) + j] = (random() & 0xff); \
|
src_u[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
|
||||||
src_v[(i * src_width / SUBSAMP_X) + j] = (random() & 0xff); \
|
src_v[(i * kWidth / SUBSAMP_X) + j] = (random() & 0xff); \
|
||||||
} \
|
} \
|
||||||
MaskCpuFlags(kCpuInitialized); \
|
MaskCpuFlags(kCpuInitialized); \
|
||||||
##FMT_A##To##FMT_B(src_y, src_width, \
|
##FMT_PLANAR##To##FMT_B(src_y, kWidth, \
|
||||||
src_u, src_width / SUBSAMP_X, \
|
src_u, kWidth / SUBSAMP_X, \
|
||||||
src_v, src_width / SUBSAMP_X, \
|
src_v, kWidth / SUBSAMP_X, \
|
||||||
dst_rgb_c, src_width * BPP_B, \
|
dst_argb_c, kWidth * BPP_B, \
|
||||||
src_width, src_height); \
|
kWidth, kHeight); \
|
||||||
MaskCpuFlags(-1); \
|
MaskCpuFlags(-1); \
|
||||||
const int runs = 1000; \
|
const int runs = 1000; \
|
||||||
for (int i = 0; i < runs; ++i) { \
|
for (int i = 0; i < runs; ++i) { \
|
||||||
##FMT_A##To##FMT_B(src_y, src_width, \
|
##FMT_PLANAR##To##FMT_B(src_y, kWidth, \
|
||||||
src_u, src_width / SUBSAMP_X, \
|
src_u, kWidth / SUBSAMP_X, \
|
||||||
src_v, src_width / SUBSAMP_X, \
|
src_v, kWidth / SUBSAMP_X, \
|
||||||
dst_rgb_opt, src_width * BPP_B, \
|
dst_argb_opt, kWidth * BPP_B, \
|
||||||
src_width, src_height); \
|
kWidth, kHeight); \
|
||||||
} \
|
} \
|
||||||
int err = 0; \
|
int err = 0; \
|
||||||
for (int i = 0; i < src_height; ++i) { \
|
for (int i = 0; i < kHeight; ++i) { \
|
||||||
for (int j = 0; j < src_width * BPP_B; ++j) { \
|
for (int j = 0; j < kWidth * BPP_B; ++j) { \
|
||||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP_B + j]) - \
|
int diff = static_cast<int>(dst_argb_c[i * kWidth * BPP_B + j]) - \
|
||||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP_B + j]); \
|
static_cast<int>(dst_argb_opt[i * kWidth * BPP_B + j]); \
|
||||||
if (abs(diff) > 2) \
|
if (abs(diff) > 2) { \
|
||||||
err++; \
|
++err; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
EXPECT_EQ(err, 0); \
|
EXPECT_EQ(err, 0); \
|
||||||
free_aligned_buffer_16(src_y) \
|
free_aligned_buffer_16(src_y) \
|
||||||
free_aligned_buffer_16(src_u) \
|
free_aligned_buffer_16(src_u) \
|
||||||
free_aligned_buffer_16(src_v) \
|
free_aligned_buffer_16(src_v) \
|
||||||
free_aligned_buffer_16(dst_rgb_c) \
|
free_aligned_buffer_16(dst_argb_c) \
|
||||||
free_aligned_buffer_16(dst_rgb_opt) \
|
free_aligned_buffer_16(dst_argb_opt) \
|
||||||
}
|
}
|
||||||
|
|
||||||
TESTPLANARTOB(I420, 2, 2, ARGB, 4)
|
TESTPLANARTOB(I420, 2, 2, ARGB, 4)
|
||||||
@ -87,41 +88,124 @@ TESTPLANARTOB(I411, 4, 1, ARGB, 4)
|
|||||||
TESTPLANARTOB(I422, 2, 1, ARGB, 4)
|
TESTPLANARTOB(I422, 2, 1, ARGB, 4)
|
||||||
TESTPLANARTOB(I444, 1, 1, ARGB, 4)
|
TESTPLANARTOB(I444, 1, 1, ARGB, 4)
|
||||||
|
|
||||||
#define TESTATOB(FMT_A, BPP_A, FMT_B, BPP_B) \
|
#define TESTATOPLANAR(FMT_A, BPP_A, FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y) \
|
||||||
TEST_F(libyuvTest, ##FMT_A##To##FMT_B##_CvsOPT) { \
|
TEST_F(libyuvTest, ##FMT_A##To##FMT_PLANAR##_CvsOPT) { \
|
||||||
const int src_width = 1280; \
|
const int kWidth = 1280; \
|
||||||
const int src_height = 720; \
|
const int kHeight = 720; \
|
||||||
align_buffer_16(src_argb, src_width * src_height * BPP_A); \
|
align_buffer_16(src_argb, (kWidth * BPP_A) * kHeight); \
|
||||||
align_buffer_16(dst_rgb_c, (src_width * BPP_B) * src_height); \
|
align_buffer_16(dst_y_c, kWidth * kHeight); \
|
||||||
align_buffer_16(dst_rgb_opt, (src_width * BPP_B) * src_height); \
|
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)); \
|
srandom(time(NULL)); \
|
||||||
for (int i = 0; i < src_height; ++i) \
|
for (int i = 0; i < kHeight; ++i) \
|
||||||
for (int j = 0; j < src_width * BPP_A; ++j) \
|
for (int j = 0; j < kWidth * BPP_A; ++j) \
|
||||||
src_argb[(i * src_width * BPP_A) + j] = (random() & 0xff); \
|
src_argb[(i * kWidth * BPP_A) + j] = (random() & 0xff); \
|
||||||
MaskCpuFlags(kCpuInitialized); \
|
MaskCpuFlags(kCpuInitialized); \
|
||||||
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
|
##FMT_A##To##FMT_PLANAR(src_argb, kWidth * BPP_A, \
|
||||||
dst_rgb_c, src_width * BPP_B, \
|
dst_y_c, kWidth, \
|
||||||
src_width, src_height); \
|
dst_u_c, kWidth / SUBSAMP_X, \
|
||||||
|
dst_v_c, kWidth / SUBSAMP_X, \
|
||||||
|
kWidth, kHeight); \
|
||||||
MaskCpuFlags(-1); \
|
MaskCpuFlags(-1); \
|
||||||
const int runs = 1000; \
|
const int runs = 1000; \
|
||||||
for (int i = 0; i < runs; ++i) { \
|
for (int i = 0; i < runs; ++i) { \
|
||||||
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
|
##FMT_A##To##FMT_PLANAR(src_argb, kWidth * BPP_A, \
|
||||||
dst_rgb_opt, src_width * BPP_B, \
|
dst_y_opt, kWidth, \
|
||||||
src_width, src_height); \
|
dst_u_opt, kWidth / SUBSAMP_X, \
|
||||||
|
dst_v_opt, kWidth / SUBSAMP_X, \
|
||||||
|
kWidth, kHeight); \
|
||||||
} \
|
} \
|
||||||
int err = 0; \
|
int err = 0; \
|
||||||
for (int i = 0; i < src_height; ++i) { \
|
for (int i = 0; i < kHeight; ++i) { \
|
||||||
for (int j = 0; j < src_width * BPP_B; ++j) { \
|
for (int j = 0; j < kWidth; ++j) { \
|
||||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP_B + j]) - \
|
int diff = static_cast<int>(dst_y_c[i * kWidth + j]) - \
|
||||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP_B + 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 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 < 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, 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, kWidth * BPP_A, \
|
||||||
|
dst_argb_opt, kWidth * BPP_B, \
|
||||||
|
kWidth, kHeight); \
|
||||||
|
} \
|
||||||
|
int err = 0; \
|
||||||
|
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) \
|
if (abs(diff) > 2) \
|
||||||
err++; \
|
err++; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
EXPECT_EQ(err, 0); \
|
EXPECT_EQ(err, 0); \
|
||||||
free_aligned_buffer_16(src_argb) \
|
free_aligned_buffer_16(src_argb) \
|
||||||
free_aligned_buffer_16(dst_rgb_c) \
|
free_aligned_buffer_16(dst_argb_c) \
|
||||||
free_aligned_buffer_16(dst_rgb_opt) \
|
free_aligned_buffer_16(dst_argb_opt) \
|
||||||
}
|
}
|
||||||
|
|
||||||
TESTATOB(ARGB, 4, ARGB, 4)
|
TESTATOB(ARGB, 4, ARGB, 4)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user