Commit 3541e46a authored by Frank Barchard's avatar Frank Barchard Committed by Commit Bot

Add H010ToARGB for 10 bit YUV to ARGB

Bug: libyuv:751
Test:  LibYUVConvertTest.H010ToARGB_Opt
Change-Id: I668d3f3810e59a4fb6611503aae1c8edc7d596e7
Reviewed-on: https://chromium-review.googlesource.com/815015
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: 's avatarrichard winterton <rrwinterton@gmail.com>
parent 2cec89a0
...@@ -152,7 +152,6 @@ static_library("libyuv_internal") { ...@@ -152,7 +152,6 @@ static_library("libyuv_internal") {
# crbug.com/538243). # crbug.com/538243).
if (!is_debug || is_nacl) { if (!is_debug || is_nacl) {
configs -= [ "//build/config/compiler:default_optimization" ] configs -= [ "//build/config/compiler:default_optimization" ]
# Enable optimize for speed (-O2) over size (-Os). # Enable optimize for speed (-O2) over size (-Os).
configs += [ "//build/config/compiler:optimize_max" ] configs += [ "//build/config/compiler:optimize_max" ]
} }
......
...@@ -342,6 +342,19 @@ int H422ToABGR(const uint8* src_y, ...@@ -342,6 +342,19 @@ int H422ToABGR(const uint8* src_y,
int width, int width,
int height); int height);
// Convert H010 to ARGB.
LIBYUV_API
int H010ToARGB(const uint16* src_y,
int src_stride_y,
const uint16* src_u,
int src_stride_u,
const uint16* src_v,
int src_stride_v,
uint8* dst_argb,
int dst_stride_argb,
int width,
int height);
// Convert H010 to AR30. // Convert H010 to AR30.
LIBYUV_API LIBYUV_API
int H010ToAR30(const uint16* src_y, int H010ToAR30(const uint16* src_y,
......
...@@ -564,6 +564,128 @@ int H010ToAR30(const uint16* src_y, ...@@ -564,6 +564,128 @@ int H010ToAR30(const uint16* src_y,
&kYuvH709Constants, 16384, width, height); &kYuvH709Constants, 16384, width, height);
} }
// Convert 10 bit YUV to ARGB with matrix
static int H010ToARGBMatrix(const uint16* src_y,
int src_stride_y,
const uint16* src_u,
int src_stride_u,
const uint16* src_v,
int src_stride_v,
uint8* dst_argb,
int dst_stride_argb,
const struct YuvConstants* yuvconstants,
int scale, // 16384 for 10 bits
int width,
int height) {
int y;
int halfwidth = (width + 1) >> 1;
void (*Convert16To8Row)(const uint16* src_y, uint8* dst_y, int scale,
int width) = Convert16To8Row_C;
void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
const uint8* v_buf, uint8* rgb_buf,
const struct YuvConstants* yuvconstants, int width) =
I422ToARGBRow_C;
if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_argb = dst_argb + (height - 1) * dst_stride_argb;
dst_stride_argb = -dst_stride_argb;
}
#if defined(HAS_CONVERT16TO8ROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
Convert16To8Row = Convert16To8Row_Any_SSSE3;
if (IS_ALIGNED(width, 16)) {
Convert16To8Row = Convert16To8Row_SSSE3;
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
Convert16To8Row = Convert16To8Row_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
Convert16To8Row = Convert16To8Row_AVX2;
}
}
#endif
#if defined(HAS_I422TOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
if (IS_ALIGNED(width, 8)) {
I422ToARGBRow = I422ToARGBRow_SSSE3;
}
}
#endif
#if defined(HAS_I422TOARGBROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
I422ToARGBRow = I422ToARGBRow_Any_AVX2;
if (IS_ALIGNED(width, 16)) {
I422ToARGBRow = I422ToARGBRow_AVX2;
}
}
#endif
#if defined(HAS_I422TOARGBROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
I422ToARGBRow = I422ToARGBRow_Any_NEON;
if (IS_ALIGNED(width, 8)) {
I422ToARGBRow = I422ToARGBRow_NEON;
}
}
#endif
#if defined(HAS_I422TOARGBROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
I422ToARGBRow = I422ToARGBRow_Any_MSA;
if (IS_ALIGNED(width, 8)) {
I422ToARGBRow = I422ToARGBRow_MSA;
}
}
#endif
align_buffer_64(row_y, width);
align_buffer_64(row_u, halfwidth);
align_buffer_64(row_v, halfwidth);
for (y = 0; y < height; ++y) {
Convert16To8Row(src_y, row_y, scale, width);
Convert16To8Row(src_u, row_u, scale, halfwidth);
Convert16To8Row(src_v, row_v, scale, halfwidth);
I422ToARGBRow(row_y, row_u, row_v, dst_argb, yuvconstants, width);
dst_argb += dst_stride_argb;
src_y += src_stride_y;
if (y & 1) {
src_u += src_stride_u;
src_v += src_stride_v;
}
}
free_aligned_buffer_64(row_y);
free_aligned_buffer_64(row_u);
free_aligned_buffer_64(row_v);
return 0;
}
// Convert H010 to ARGB.
LIBYUV_API
int H010ToARGB(const uint16* src_y,
int src_stride_y,
const uint16* src_u,
int src_stride_u,
const uint16* src_v,
int src_stride_v,
uint8* dst_argb,
int dst_stride_argb,
int width,
int height) {
return H010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
src_stride_v, dst_argb, dst_stride_argb,
&kYuvH709Constants, 16384, width, height);
}
// Convert I444 to ARGB with matrix // Convert I444 to ARGB with matrix
static int I444ToARGBMatrix(const uint8* src_y, static int I444ToARGBMatrix(const uint8* src_y,
int src_stride_y, int src_stride_y,
......
...@@ -1935,7 +1935,8 @@ TEST_F(LibYUVConvertTest, RotateWithARGBSource) { ...@@ -1935,7 +1935,8 @@ TEST_F(LibYUVConvertTest, RotateWithARGBSource) {
#ifdef HAS_ARGBTOAR30ROW_AVX2 #ifdef HAS_ARGBTOAR30ROW_AVX2
TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) { TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) {
const int kPixels = benchmark_width_ * benchmark_height_; // ARGBToAR30Row_AVX2 expects a multiple of 8 pixels.
const int kPixels = (benchmark_width_ * benchmark_height_ + 7) & ~7;
align_buffer_page_end(src, kPixels * 4); align_buffer_page_end(src, kPixels * 4);
align_buffer_page_end(dst_opt, kPixels * 4); align_buffer_page_end(dst_opt, kPixels * 4);
align_buffer_page_end(dst_c, kPixels * 4); align_buffer_page_end(dst_c, kPixels * 4);
...@@ -2037,5 +2038,6 @@ TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) { ...@@ -2037,5 +2038,6 @@ TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) {
BPP_C) BPP_C)
TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2, AR30, 4) TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2, AR30, 4)
TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
} // namespace libyuv } // namespace libyuv
...@@ -147,6 +147,8 @@ static int FileExists(const char* file_name) { ...@@ -147,6 +147,8 @@ static int FileExists(const char* file_name) {
TEST_F(LibYUVBaseTest, TestLinuxNeon) { TEST_F(LibYUVBaseTest, TestLinuxNeon) {
if (FileExists("../../unit_test/testdata/arm_v7.txt")) { if (FileExists("../../unit_test/testdata/arm_v7.txt")) {
printf("Note: testing to load \"../../unit_test/testdata/arm_v7.txt\"\n");
EXPECT_EQ(0, ArmCpuCaps("../../unit_test/testdata/arm_v7.txt")); EXPECT_EQ(0, ArmCpuCaps("../../unit_test/testdata/arm_v7.txt"));
EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/tegra3.txt")); EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/tegra3.txt"));
EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/juno.txt")); EXPECT_EQ(kCpuHasNEON, ArmCpuCaps("../../unit_test/testdata/juno.txt"));
......
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