diff options
Diffstat (limited to 'remoting/host/differ_block.cc')
-rw-r--r-- | remoting/host/differ_block.cc | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/remoting/host/differ_block.cc b/remoting/host/differ_block.cc index 4dfe58c..f7b785d 100644 --- a/remoting/host/differ_block.cc +++ b/remoting/host/differ_block.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "differ_block.h" +#include "remoting/host/differ_block.h" #include <stdlib.h> @@ -20,11 +20,6 @@ namespace remoting { -// TODO(fbarchard): Use common header for block size. -const int kBlockWidth = 32; -const int kBlockHeight = 32; -const int kBytesPerPixel = 3; - #if USE_SSE2 int BlockDifference(const uint8* image1, const uint8* image2, int stride) { __m128i acc = _mm_setzero_si128(); @@ -58,25 +53,48 @@ int BlockDifference(const uint8* image1, const uint8* image2, int stride) { v1 = _mm_loadu_si128(i2 + 5); sad = _mm_sad_epu8(v0, v1); acc = _mm_adds_epu16(acc, sad); + v0 = _mm_loadu_si128(i1 + 6); + v1 = _mm_loadu_si128(i2 + 6); + sad = _mm_sad_epu8(v0, v1); + acc = _mm_adds_epu16(acc, sad); + v0 = _mm_loadu_si128(i1 + 7); + v1 = _mm_loadu_si128(i2 + 7); + sad = _mm_sad_epu8(v0, v1); + acc = _mm_adds_epu16(acc, sad); + sad = _mm_shuffle_epi32(acc, 0xEE); // [acc3, acc2, acc3, acc2] + sad = _mm_adds_epu16(sad, acc); + int diff = _mm_cvtsi128_si32(sad); + if (diff) { + return 1; + } image1 += stride; image2 += stride; } - sad = _mm_shuffle_epi32(acc, 0xEE); // [acc3, acc2, acc3, acc2] - sad = _mm_adds_epu16(sad, acc); - int diff = _mm_cvtsi128_si32(sad); - return diff; + return 0; } #else int BlockDifference(const uint8* image1, const uint8* image2, int stride) { - int diff = 0; - for (int y = 0; y < kBlockHeight; ++y) { - for (int x = 0; x < kBlockWidth * kBytesPerPixel; ++x) { - diff += abs(image1[x] - image2[x]); + // Number of uint64s in each row of the block. + // This must be an integral number. + int int64s_per_row = (kBlockWidth * kBytesPerPixel) / sizeof(uint64); + + for (int y = 0; y < kBlockHeight; y++) { + const uint64* prev = reinterpret_cast<const uint64*>(image1); + const uint64* curr = reinterpret_cast<const uint64*>(image2); + + // Check each row in uint64-sized chunks. + // Note that this check may straddle multiple pixels. This is OK because + // we're interested in identifying whether or not there was change - we + // don't care what the actual change is. + for (int x = 0; x < int64s_per_row; x++) { + if (*prev++ != *curr++) { + return 1; + } } image1 += stride; image2 += stride; } - return diff; + return 0; } #endif |