diff --git a/README.chromium b/README.chromium index ab3fa706d..5c571e2bc 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1691 +Version: 1692 License: BSD License File: LICENSE diff --git a/include/libyuv/convert_from.h b/include/libyuv/convert_from.h index dbdcb00af..ad8ae1897 100644 --- a/include/libyuv/convert_from.h +++ b/include/libyuv/convert_from.h @@ -291,6 +291,7 @@ int I420ToARGB4444(const uint8_t* src_y, int dst_stride_frame, int width, int height); + // Convert I420 to AR30. LIBYUV_API int I420ToAR30(const uint8_t* src_y, @@ -304,6 +305,19 @@ int I420ToAR30(const uint8_t* src_y, int width, int height); +// Convert H420 to AR30. +LIBYUV_API +int H420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height); + // Convert I420 to specified format. // "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the // buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 8c78b65bf..dc96d55e7 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 1691 +#define LIBYUV_VERSION 1692 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/convert_from.cc b/source/convert_from.cc index eb4631352..bc90d3c57 100644 --- a/source/convert_from.cc +++ b/source/convert_from.cc @@ -1210,6 +1210,23 @@ int I420ToAR30(const uint8_t* src_y, &kYuvI601Constants, width, height); } +// Convert H420 to AR30. +LIBYUV_API +int H420ToAR30(const uint8_t* src_y, + int src_stride_y, + const uint8_t* src_u, + int src_stride_u, + const uint8_t* src_v, + int src_stride_v, + uint8_t* dst_ar30, + int dst_stride_ar30, + int width, + int height) { + return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, + src_stride_v, dst_ar30, dst_stride_ar30, + &kYvuH709Constants, width, height); +} + // Convert I420 to specified format LIBYUV_API int ConvertFromI420(const uint8_t* y, diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index e8ef2349e..7c5526986 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -2106,6 +2106,7 @@ static int Clamp10(int y) { return y; } +// Test 8 bit YUV to 8 bit RGB TEST_F(LibYUVConvertTest, TestH420ToARGB) { const int kSize = 256; int histogram_b[256]; @@ -2163,6 +2164,7 @@ TEST_F(LibYUVConvertTest, TestH420ToARGB) { free_aligned_buffer_page_end(argb_pixels); } +// Test 10 bit YUV to 8 bit RGB TEST_F(LibYUVConvertTest, TestH010ToARGB) { const int kSize = 1024; int histogram_b[1024]; @@ -2220,6 +2222,7 @@ TEST_F(LibYUVConvertTest, TestH010ToARGB) { free_aligned_buffer_page_end(argb_pixels); } +// Test 10 bit YUV to 10 bit RGB // Caveat: Result is near due to float rounding in expected result. TEST_F(LibYUVConvertTest, TestH010ToAR30) { const int kSize = 1024; @@ -2279,4 +2282,63 @@ TEST_F(LibYUVConvertTest, TestH010ToAR30) { free_aligned_buffer_page_end(ar30_pixels); } +// Test 8 bit YUV to 10 bit RGB +TEST_F(LibYUVConvertTest, TestH420ToAR30) { + const int kSize = 256; + const int kHistSize = 1024; + int histogram_b[kHistSize]; + int histogram_g[kHistSize]; + int histogram_r[kHistSize]; + memset(histogram_b, 0, sizeof(histogram_b)); + memset(histogram_g, 0, sizeof(histogram_g)); + memset(histogram_r, 0, sizeof(histogram_r)); + align_buffer_page_end(orig_yuv, kSize + kSize / 2 * 2); + align_buffer_page_end(ar30_pixels, kSize * 4); + uint8_t* orig_y = orig_yuv; + uint8_t* orig_u = orig_y + kSize; + uint8_t* orig_v = orig_u + kSize / 2; + + // Test grey scale + for (int i = 0; i < kSize; ++i) { + orig_y[i] = i; + } + for (int i = 0; i < kSize / 2; ++i) { + orig_u[i] = 128; // 128 is 0. + orig_v[i] = 128; + } + + H420ToAR30(orig_y, 0, orig_u, 0, orig_v, 0, ar30_pixels, 0, kSize, 1); + + for (int i = 0; i < kSize; ++i) { + int b10 = reinterpret_cast(ar30_pixels)[i] & 1023; + int g10 = (reinterpret_cast(ar30_pixels)[i] >> 10) & 1023; + int r10 = (reinterpret_cast(ar30_pixels)[i] >> 20) & 1023; + int a2 = (reinterpret_cast(ar30_pixels)[i] >> 30) & 3; + ++histogram_b[b10]; + ++histogram_g[g10]; + ++histogram_r[r10]; + int expected_y = Clamp10(static_cast((i - 16) * 1.164f * 4.f)); + EXPECT_NEAR(b10, expected_y, 4); + EXPECT_NEAR(g10, expected_y, 4); + EXPECT_NEAR(r10, expected_y, 4); + EXPECT_EQ(a2, 3); + } + + int count_b = 0; + int count_g = 0; + int count_r = 0; + for (int i = 0; i < kHistSize; ++i) { + if (histogram_b[i]) + ++count_b; + if (histogram_g[i]) + ++count_g; + if (histogram_r[i]) + ++count_r; + } + printf("uniques: B %d, G, %d, R %d\n", count_b, count_g, count_r); + + free_aligned_buffer_page_end(orig_yuv); + free_aligned_buffer_page_end(ar30_pixels); +} + } // namespace libyuv