Commit 1734712a authored by Frank Barchard's avatar Frank Barchard Committed by Commit Bot

Fix odd length HammingDistance

If length of HammingDistance was not a multiple of 4,
the result was incorrect.  The old tests did not catch this
so a new test is done to count 1s.

Bug: libyuv:740
Test: LibYUVCompareTest.TestHammingDistance
Change-Id: I93db5437821c597f1f162ac263d4a594bb83231f
Reviewed-on: https://chromium-review.googlesource.com/699614Reviewed-by: 's avatarrichard winterton <rrwinterton@gmail.com>
Reviewed-by: 's avatarCheng Wang <wangcheng@google.com>
Reviewed-by: 's avatarFrank Barchard <fbarchard@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
parent fecd7417
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 1672
Version: 1673
License: BSD
License File: LICENSE
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1672
#define LIBYUV_VERSION 1673
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -115,8 +115,9 @@ uint64 ComputeHammingDistance(const uint8* src_a,
const uint8* src_b,
int count) {
const int kBlockSize = 65536;
const int kSimdSize = 64;
// SIMD for multiple of 64, and C for remainder
int remainder = count & (kBlockSize - 1) & ~63;
int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1);
uint64 diff = 0;
int i;
uint32 (*HammingDistance)(const uint8* src_a, const uint8* src_b, int count) =
......@@ -159,7 +160,7 @@ uint64 ComputeHammingDistance(const uint8* src_a,
src_a += remainder;
src_b += remainder;
}
remainder = count & 31;
remainder = count & (kSimdSize - 1);
if (remainder) {
diff += HammingDistance_C(src_a, src_b, remainder);
}
......
......@@ -18,7 +18,7 @@ extern "C" {
#endif
#if ORIGINAL_OPT
uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) {
uint32 HammingDistance_C1(const uint8* src_a, const uint8* src_b, int count) {
uint32 diff = 0u;
int i;
......@@ -58,6 +58,16 @@ uint32 HammingDistance_C(const uint8* src_a, const uint8* src_b, int count) {
src_a += 4;
src_b += 4;
}
for (; i < count; ++i) {
uint32 x = *src_a ^ *src_b;
uint32 u = x - ((x >> 1) & 0x55);
u = ((u >> 2) & 0x33) + (u & 0x33);
diff += (u + (u >> 4)) & 0x0f;
src_a += 1;
src_b += 1;
}
return diff;
}
......
......@@ -316,6 +316,23 @@ TEST_F(LibYUVCompareTest, BenchmarkHammingDistance) {
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVCompareTest, TestHammingDistance) {
align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
memset(src_a, 255u, benchmark_width_ * benchmark_height_);
memset(src_b, 0, benchmark_width_ * benchmark_height_);
uint64 h1 = 0;
for (int i = 0; i < benchmark_iterations_; ++i) {
h1 = ComputeHammingDistance(src_a, src_b,
benchmark_width_ * benchmark_height_);
}
EXPECT_EQ(benchmark_width_ * benchmark_height_ * 8ULL, h1);
free_aligned_buffer_page_end(src_a);
free_aligned_buffer_page_end(src_b);
}
TEST_F(LibYUVCompareTest, BenchmarkSumSquareError_Opt) {
const int kMaxWidth = 4096 * 3;
align_buffer_page_end(src_a, kMaxWidth);
......
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