/* * Copyright (c) 2018 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
// Negate 16-bit integers in a when the corresponding signed 16-bit // integer in b is negative. staticINLINE int16x8_t vec_sign(int16x8_t a, int16x8_t b) { const int16x8_t mask = vec_sra(b, vec_shift_sign_s16); return vec_xor(vec_add(a, mask), mask);
}
// Sets the value of a 32-bit integers to 1 when the corresponding value in a is // negative. staticINLINE int32x4_t vec_is_neg(int32x4_t a) { return vec_sr(a, vec_shift_sign_s32);
}
// Multiply the packed 16-bit integers in a and b, producing intermediate 32-bit // integers, and return the high 16 bits of the intermediate integers. // (a * b) >> 16 staticINLINE int16x8_t vec_mulhi(int16x8_t a, int16x8_t b) { // madds does ((A * B) >>15) + C, we need >> 16, so we perform an extra right // shift. return vec_sra(vec_madds(a, b, vec_zeros_s16), vec_ones_u16);
}
// Quantization function used for 32x32 blocks. staticINLINE int16x8_t quantize_coeff_32(int16x8_t coeff, int16x8_t coeff_abs,
int16x8_t round, int16x8_t quant,
int16x8_t quant_shift,
bool16x8_t mask) { const int16x8_t rounded = vec_vaddshs(coeff_abs, round);
int16x8_t qcoeff = vec_mulhi(rounded, quant);
qcoeff = vec_add(qcoeff, rounded); // 32x32 blocks require an extra multiplication by 2, this compensates for the // extra right shift added in vec_mulhi, as such vec_madds can be used // directly instead of vec_mulhi (((a * b) >> 15) >> 1) << 1 == (a * b >> 15)
qcoeff = vec_madds(qcoeff, quant_shift, vec_zeros_s16);
qcoeff = vec_sign(qcoeff, coeff); return vec_and(qcoeff, mask);
}
// DeQuantization function used for 32x32 blocks. Quantized coeff of 32x32 // blocks are twice as big as for other block sizes. As such, using // vec_mladd results in overflow. staticINLINE int16x8_t dequantize_coeff_32(int16x8_t qcoeff,
int16x8_t dequant) {
int32x4_t dqcoeffe = vec_mule(qcoeff, dequant);
int32x4_t dqcoeffo = vec_mulo(qcoeff, dequant); // Add 1 if negative to round towards zero because the C uses division.
dqcoeffe = vec_add(dqcoeffe, vec_is_neg(dqcoeffe));
dqcoeffo = vec_add(dqcoeffo, vec_is_neg(dqcoeffo));
dqcoeffe = vec_sra(dqcoeffe, vec_ones_u32);
dqcoeffo = vec_sra(dqcoeffo, vec_ones_u32); return (int16x8_t)vec_perm(dqcoeffe, dqcoeffo, vec_perm_odd_even_pack);
}
// Compare packed 16-bit integers across a, and return the maximum value in // every element. Returns a vector containing the biggest value across vector a. staticINLINE int16x8_t vec_max_across(int16x8_t a) {
a = vec_max(a, vec_perm(a, a, vec_perm64));
a = vec_max(a, vec_perm(a, a, vec_perm32)); return vec_max(a, vec_perm(a, a, vec_perm16));
}
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.