diff options
-rw-r--r-- | BUILD.gn | 4 | ||||
-rw-r--r-- | OWNERS | 1 | ||||
-rw-r--r-- | README.chromium | 2 | ||||
-rw-r--r-- | include/libyuv/planar_functions.h | 8 | ||||
-rw-r--r-- | include/libyuv/version.h | 2 | ||||
-rw-r--r-- | source/planar_functions.cc | 67 | ||||
-rw-r--r-- | unit_test/planar_test.cc | 87 |
7 files changed, 164 insertions, 7 deletions
@@ -27,10 +27,6 @@ config("libyuv_config") { if (is_android && current_cpu != "arm64") { ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker" ] } - - if (!libyuv_use_neon) { - defines = [ "LIBYUV_DISABLE_NEON" ] - } } # This target is built when no specific target is specified on the command line. @@ -1,7 +1,6 @@ mbonadei@chromium.org fbarchard@chromium.org magjed@chromium.org -pbos@chromium.org per-file *.gn=mbonadei@chromium.org per-file .gitignore=* diff --git a/README.chromium b/README.chromium index 76b54121..b6d85b73 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1823 +Version: 1824 License: BSD License File: LICENSE diff --git a/include/libyuv/planar_functions.h b/include/libyuv/planar_functions.h index 972ca9e3..15c7d457 100644 --- a/include/libyuv/planar_functions.h +++ b/include/libyuv/planar_functions.h @@ -461,6 +461,14 @@ int YUY2ToY(const uint8_t* src_yuy2, int width, int height); +LIBYUV_API +int UYVYToY(const uint8_t* src_uyvy, + int src_stride_uyvy, + uint8_t* dst_y, + int dst_stride_y, + int width, + int height); + // Convert I420 to I400. (calls CopyPlane ignoring u/v). LIBYUV_API int I420ToI400(const uint8_t* src_y, diff --git a/include/libyuv/version.h b/include/libyuv/version.h index d0b94fee..8afef0ed 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1823 +#define LIBYUV_VERSION 1824 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/planar_functions.cc b/source/planar_functions.cc index c698b01a..53e74679 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -2053,6 +2053,73 @@ int YUY2ToY(const uint8_t* src_yuy2, return 0; } +// Convert UYVY to Y. +LIBYUV_API +int UYVYToY(const uint8_t* src_uyvy, + int src_stride_uyvy, + uint8_t* dst_y, + int dst_stride_y, + int width, + int height) { + int y; + void (*UYVYToYRow)(const uint8_t* src_uyvy, uint8_t* dst_y, int width) = + UYVYToYRow_C; + if (!src_uyvy || !dst_y || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; + src_stride_uyvy = -src_stride_uyvy; + } + // Coalesce rows. + if (src_stride_uyvy == width * 2 && dst_stride_y == width) { + width *= height; + height = 1; + src_stride_uyvy = dst_stride_y = 0; + } +#if defined(HAS_UYVYTOYROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + UYVYToYRow = UYVYToYRow_Any_SSE2; + if (IS_ALIGNED(width, 16)) { + UYVYToYRow = UYVYToYRow_SSE2; + } + } +#endif +#if defined(HAS_UYVYTOYROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + UYVYToYRow = UYVYToYRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + UYVYToYRow = UYVYToYRow_AVX2; + } + } +#endif +#if defined(HAS_UYVYTOYROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + UYVYToYRow = UYVYToYRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + UYVYToYRow = UYVYToYRow_NEON; + } + } +#endif +#if defined(HAS_UYVYTOYROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + UYVYToYRow = UYVYToYRow_Any_MSA; + if (IS_ALIGNED(width, 32)) { + UYVYToYRow = UYVYToYRow_MSA; + } + } +#endif + + for (y = 0; y < height; ++y) { + UYVYToYRow(src_uyvy, dst_y, width); + src_uyvy += src_stride_uyvy; + dst_y += dst_stride_y; + } + return 0; +} + // Mirror a plane of data. // See Also I400Mirror LIBYUV_API diff --git a/unit_test/planar_test.cc b/unit_test/planar_test.cc index 76fec3ec..833091a1 100644 --- a/unit_test/planar_test.cc +++ b/unit_test/planar_test.cc @@ -3463,6 +3463,64 @@ TEST_F(LibYUVPlanarTest, Convert16To8Plane) { free_aligned_buffer_page_end(dst_pixels_y_c); } +TEST_F(LibYUVPlanarTest, YUY2ToY) { + const int kPixels = benchmark_width_ * benchmark_height_; + align_buffer_page_end(src_pixels_y, kPixels * 2); + align_buffer_page_end(dst_pixels_y_opt, kPixels); + align_buffer_page_end(dst_pixels_y_c, kPixels); + + MemRandomize(src_pixels_y, kPixels * 2); + memset(dst_pixels_y_opt, 0, kPixels); + memset(dst_pixels_y_c, 1, kPixels); + + MaskCpuFlags(disable_cpu_flags_); + YUY2ToY(src_pixels_y, benchmark_width_ * 2, dst_pixels_y_c, + benchmark_width_, benchmark_width_, benchmark_height_); + MaskCpuFlags(benchmark_cpu_info_); + + for (int i = 0; i < benchmark_iterations_; ++i) { + YUY2ToY(src_pixels_y, benchmark_width_ * 2, dst_pixels_y_opt, + benchmark_width_, benchmark_width_, benchmark_height_); + } + + for (int i = 0; i < kPixels; ++i) { + EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); + } + + free_aligned_buffer_page_end(src_pixels_y); + free_aligned_buffer_page_end(dst_pixels_y_opt); + free_aligned_buffer_page_end(dst_pixels_y_c); +} + +TEST_F(LibYUVPlanarTest, UYVYToY) { + const int kPixels = benchmark_width_ * benchmark_height_; + align_buffer_page_end(src_pixels_y, kPixels * 2); + align_buffer_page_end(dst_pixels_y_opt, kPixels); + align_buffer_page_end(dst_pixels_y_c, kPixels); + + MemRandomize(src_pixels_y, kPixels * 2); + memset(dst_pixels_y_opt, 0, kPixels); + memset(dst_pixels_y_c, 1, kPixels); + + MaskCpuFlags(disable_cpu_flags_); + UYVYToY(src_pixels_y, benchmark_width_ * 2, dst_pixels_y_c, + benchmark_width_, benchmark_width_, benchmark_height_); + MaskCpuFlags(benchmark_cpu_info_); + + for (int i = 0; i < benchmark_iterations_; ++i) { + UYVYToY(src_pixels_y, benchmark_width_ * 2, dst_pixels_y_opt, + benchmark_width_, benchmark_width_, benchmark_height_); + } + + for (int i = 0; i < kPixels; ++i) { + EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); + } + + free_aligned_buffer_page_end(src_pixels_y); + free_aligned_buffer_page_end(dst_pixels_y_opt); + free_aligned_buffer_page_end(dst_pixels_y_c); +} + #ifdef ENABLE_ROW_TESTS // TODO(fbarchard): Improve test for more platforms. #ifdef HAS_CONVERT16TO8ROW_AVX2 @@ -3509,6 +3567,35 @@ TEST_F(LibYUVPlanarTest, Convert16To8Row_Opt) { free_aligned_buffer_page_end(dst_pixels_y_c); } #endif // HAS_CONVERT16TO8ROW_AVX2 + +#ifdef HAS_UYVYTOYROW_NEON +TEST_F(LibYUVPlanarTest, UYVYToYRow_Opt) { + // NEON does multiple of 16, so round count up + const int kPixels = (benchmark_width_ * benchmark_height_ + 15) & ~15; + align_buffer_page_end(src_pixels_y, kPixels * 2); + align_buffer_page_end(dst_pixels_y_opt, kPixels); + align_buffer_page_end(dst_pixels_y_c, kPixels); + + MemRandomize(src_pixels_y, kPixels * 2); + memset(dst_pixels_y_opt, 0, kPixels); + memset(dst_pixels_y_c, 1, kPixels); + + UYVYToYRow_C(src_pixels_y, dst_pixels_y_c, kPixels); + + for (int i = 0; i < benchmark_iterations_; ++i) { + UYVYToYRow_NEON(src_pixels_y, dst_pixels_y_opt, kPixels); + } + + for (int i = 0; i < kPixels; ++i) { + EXPECT_EQ(dst_pixels_y_opt[i], dst_pixels_y_c[i]); + } + + free_aligned_buffer_page_end(src_pixels_y); + free_aligned_buffer_page_end(dst_pixels_y_opt); + free_aligned_buffer_page_end(dst_pixels_y_c); +} +#endif // HAS_UYVYTOYROW_NEON + #endif // ENABLE_ROW_TESTS TEST_F(LibYUVPlanarTest, Convert8To16Plane) { |