/* * Copyright (c) 2019, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
template <typename OutputType> void ReferenceHadamard8x8(const int16_t *a, int a_stride, OutputType *b) {
OutputType input[64];
OutputType buf[64]; for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) {
input[i * 8 + j] = static_cast<OutputType>(a[i * a_stride + j]);
}
} for (int i = 0; i < 8; ++i) HadamardLoop(input + i, buf + i * 8); for (int i = 0; i < 8; ++i) HadamardLoop(buf + i, b + i * 8);
// Extra transpose to match SSE2 behavior (i.e., aom_hadamard_8x8 and // aom_hadamard_lp_8x8). for (int i = 0; i < 8; i++) { for (int j = i + 1; j < 8; j++) {
OutputType temp = b[j * 8 + i];
b[j * 8 + i] = b[i * 8 + j];
b[i * 8 + j] = temp;
}
}
}
template <typename OutputType> void ReferenceHadamard8x8Dual(const int16_t *a, int a_stride, OutputType *b) { /* The source is a 8x16 block. The destination is rearranged to 8x16.
* Input is 9 bit. */
ReferenceHadamard8x8(a, a_stride, b);
ReferenceHadamard8x8(a + 8, a_stride, b + 64);
}
template <typename OutputType> void ReferenceHadamard16x16(const int16_t *a, int a_stride, OutputType *b, bool shift) { /* The source is a 16x16 block. The destination is rearranged to 8x32.
* Input is 9 bit. */
ReferenceHadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
ReferenceHadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
ReferenceHadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
ReferenceHadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
/* Overlay the 8x8 blocks and combine. */ for (int i = 0; i < 64; ++i) { /* 8x8 steps the range up to 15 bits. */ const OutputType a0 = b[0]; const OutputType a1 = b[64]; const OutputType a2 = b[128]; const OutputType a3 = b[192];
template <typename HadamardFuncType> struct FuncWithSize {
FuncWithSize(HadamardFuncType f, int bw, int bh)
: func(f), block_width(bw), block_height(bh) {}
HadamardFuncType func; int block_width; int block_height;
};
using HadamardFuncWithSize = FuncWithSize<HadamardFunc>; using HadamardLPFuncWithSize = FuncWithSize<HadamardLPFunc>; using HadamardLP8x8DualFuncWithSize = FuncWithSize<HadamardLP8x8DualFunc>;
// The Rand() function generates values in the range [-((1 << BitDepth) - 1), // (1 << BitDepth) - 1]. This is because the input to the Hadamard transform // is the residual pixel, which is defined as 'source pixel - predicted // pixel'. Source pixel and predicted pixel take values in the range // [0, (1 << BitDepth) - 1] and thus the residual pixel ranges from // -((1 << BitDepth) - 1) to ((1 << BitDepth) - 1). virtual int16_t Rand() = 0;
for (int i = 0; i < block_size; ++i) a[i] = Rand();
ReferenceHadamard(a, bw_, b_ref, bw_, bh_, shift_);
API_REGISTER_STATE_CHECK(h_func_(a, bw_, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + block_size);
std::sort(b_ref, b_ref + block_size);
EXPECT_EQ(memcmp(b, b_ref, sizeof(b)), 0);
}
// The order of the output is not important. Sort before checking.
std::sort(b, b + block_size);
std::sort(b_ref, b_ref + block_size);
EXPECT_EQ(memcmp(b, b_ref, sizeof(b)), 0);
}
}
DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]);
DECLARE_ALIGNED(16, OutputType, b[kMaxBlockSize]);
memset(a, 0, sizeof(a)); for (int i = 0; i < block_size * 8; ++i) a[i] = Rand();
OutputType b_ref[kMaxBlockSize]; for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
ReferenceHadamard(a, i, b_ref, bw_, bh_, shift_);
API_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + block_size);
std::sort(b_ref, b_ref + block_size);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.