Merge "Factor forward 2D-DCT transforms into vpx_dsp"
This commit is contained in:
commit
f0f00251ea
@ -19,6 +19,7 @@
|
||||
#include "test/util.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
@ -921,7 +922,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
// TODO(jingning) Re-enable the mips/msa unit test.
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE && 0
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans16x16DCT,
|
||||
::testing::Values(
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "test/util.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
@ -537,7 +538,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
// TODO(jingning) Re-enable the mips/msa unit test.
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE && 0
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans4x4DCT,
|
||||
::testing::Values(
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "test/util.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
@ -772,7 +773,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
// TODO(jingning) Re-enable the mips/msa unit test.
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE && 0
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, FwdTrans8x8DCT,
|
||||
::testing::Values(
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "test/util.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp9/common/vp9_blockd.h"
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
@ -829,21 +829,12 @@ if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
add_proto qw/void vp9_fdct4x4_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4_1 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8_1 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16_1 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct32x32_1 sse2/;
|
||||
|
||||
@ -868,21 +859,12 @@ if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
add_proto qw/void vp9_fdct4x4_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4_1 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4 sse2 msa/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8_1 sse2 neon msa/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8 sse2 neon msa/, "$ssse3_x86_64_x86inc";
|
||||
|
||||
add_proto qw/void vp9_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16_1 sse2 msa/;
|
||||
|
||||
add_proto qw/void vp9_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16 sse2 msa/;
|
||||
|
||||
add_proto qw/void vp9_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct32x32_1 sse2 msa/;
|
||||
|
||||
@ -944,21 +926,12 @@ if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
add_proto qw/void vp9_highbd_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fwht4x4/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct4x4 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct8x8_1/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct8x8 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct16x16_1/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct16x16 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct32x32_1/;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
|
||||
#include "vp9/common/vp9_blockd.h"
|
||||
@ -49,193 +50,3 @@ void vp9_fdct8x8_quant_neon(const int16_t *input, int stride,
|
||||
quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
|
||||
dequant_ptr, eob_ptr, scan_ptr, iscan_ptr);
|
||||
}
|
||||
|
||||
void vp9_fdct8x8_neon(const int16_t *input, int16_t *final_output, int stride) {
|
||||
int i;
|
||||
// stage 1
|
||||
int16x8_t input_0 = vshlq_n_s16(vld1q_s16(&input[0 * stride]), 2);
|
||||
int16x8_t input_1 = vshlq_n_s16(vld1q_s16(&input[1 * stride]), 2);
|
||||
int16x8_t input_2 = vshlq_n_s16(vld1q_s16(&input[2 * stride]), 2);
|
||||
int16x8_t input_3 = vshlq_n_s16(vld1q_s16(&input[3 * stride]), 2);
|
||||
int16x8_t input_4 = vshlq_n_s16(vld1q_s16(&input[4 * stride]), 2);
|
||||
int16x8_t input_5 = vshlq_n_s16(vld1q_s16(&input[5 * stride]), 2);
|
||||
int16x8_t input_6 = vshlq_n_s16(vld1q_s16(&input[6 * stride]), 2);
|
||||
int16x8_t input_7 = vshlq_n_s16(vld1q_s16(&input[7 * stride]), 2);
|
||||
for (i = 0; i < 2; ++i) {
|
||||
int16x8_t out_0, out_1, out_2, out_3, out_4, out_5, out_6, out_7;
|
||||
const int16x8_t v_s0 = vaddq_s16(input_0, input_7);
|
||||
const int16x8_t v_s1 = vaddq_s16(input_1, input_6);
|
||||
const int16x8_t v_s2 = vaddq_s16(input_2, input_5);
|
||||
const int16x8_t v_s3 = vaddq_s16(input_3, input_4);
|
||||
const int16x8_t v_s4 = vsubq_s16(input_3, input_4);
|
||||
const int16x8_t v_s5 = vsubq_s16(input_2, input_5);
|
||||
const int16x8_t v_s6 = vsubq_s16(input_1, input_6);
|
||||
const int16x8_t v_s7 = vsubq_s16(input_0, input_7);
|
||||
// fdct4(step, step);
|
||||
int16x8_t v_x0 = vaddq_s16(v_s0, v_s3);
|
||||
int16x8_t v_x1 = vaddq_s16(v_s1, v_s2);
|
||||
int16x8_t v_x2 = vsubq_s16(v_s1, v_s2);
|
||||
int16x8_t v_x3 = vsubq_s16(v_s0, v_s3);
|
||||
// fdct4(step, step);
|
||||
int32x4_t v_t0_lo = vaddl_s16(vget_low_s16(v_x0), vget_low_s16(v_x1));
|
||||
int32x4_t v_t0_hi = vaddl_s16(vget_high_s16(v_x0), vget_high_s16(v_x1));
|
||||
int32x4_t v_t1_lo = vsubl_s16(vget_low_s16(v_x0), vget_low_s16(v_x1));
|
||||
int32x4_t v_t1_hi = vsubl_s16(vget_high_s16(v_x0), vget_high_s16(v_x1));
|
||||
int32x4_t v_t2_lo = vmull_n_s16(vget_low_s16(v_x2), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t2_hi = vmull_n_s16(vget_high_s16(v_x2), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t3_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t3_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_24_64);
|
||||
v_t2_lo = vmlal_n_s16(v_t2_lo, vget_low_s16(v_x3), (int16_t)cospi_8_64);
|
||||
v_t2_hi = vmlal_n_s16(v_t2_hi, vget_high_s16(v_x3), (int16_t)cospi_8_64);
|
||||
v_t3_lo = vmlsl_n_s16(v_t3_lo, vget_low_s16(v_x2), (int16_t)cospi_8_64);
|
||||
v_t3_hi = vmlsl_n_s16(v_t3_hi, vget_high_s16(v_x2), (int16_t)cospi_8_64);
|
||||
v_t0_lo = vmulq_n_s32(v_t0_lo, cospi_16_64);
|
||||
v_t0_hi = vmulq_n_s32(v_t0_hi, cospi_16_64);
|
||||
v_t1_lo = vmulq_n_s32(v_t1_lo, cospi_16_64);
|
||||
v_t1_hi = vmulq_n_s32(v_t1_hi, cospi_16_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x4_t e = vrshrn_n_s32(v_t2_lo, DCT_CONST_BITS);
|
||||
const int16x4_t f = vrshrn_n_s32(v_t2_hi, DCT_CONST_BITS);
|
||||
const int16x4_t g = vrshrn_n_s32(v_t3_lo, DCT_CONST_BITS);
|
||||
const int16x4_t h = vrshrn_n_s32(v_t3_hi, DCT_CONST_BITS);
|
||||
out_0 = vcombine_s16(a, c); // 00 01 02 03 40 41 42 43
|
||||
out_2 = vcombine_s16(e, g); // 20 21 22 23 60 61 62 63
|
||||
out_4 = vcombine_s16(b, d); // 04 05 06 07 44 45 46 47
|
||||
out_6 = vcombine_s16(f, h); // 24 25 26 27 64 65 66 67
|
||||
}
|
||||
// Stage 2
|
||||
v_x0 = vsubq_s16(v_s6, v_s5);
|
||||
v_x1 = vaddq_s16(v_s6, v_s5);
|
||||
v_t0_lo = vmull_n_s16(vget_low_s16(v_x0), (int16_t)cospi_16_64);
|
||||
v_t0_hi = vmull_n_s16(vget_high_s16(v_x0), (int16_t)cospi_16_64);
|
||||
v_t1_lo = vmull_n_s16(vget_low_s16(v_x1), (int16_t)cospi_16_64);
|
||||
v_t1_hi = vmull_n_s16(vget_high_s16(v_x1), (int16_t)cospi_16_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x8_t ab = vcombine_s16(a, b);
|
||||
const int16x8_t cd = vcombine_s16(c, d);
|
||||
// Stage 3
|
||||
v_x0 = vaddq_s16(v_s4, ab);
|
||||
v_x1 = vsubq_s16(v_s4, ab);
|
||||
v_x2 = vsubq_s16(v_s7, cd);
|
||||
v_x3 = vaddq_s16(v_s7, cd);
|
||||
}
|
||||
// Stage 4
|
||||
v_t0_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_4_64);
|
||||
v_t0_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_4_64);
|
||||
v_t0_lo = vmlal_n_s16(v_t0_lo, vget_low_s16(v_x0), (int16_t)cospi_28_64);
|
||||
v_t0_hi = vmlal_n_s16(v_t0_hi, vget_high_s16(v_x0), (int16_t)cospi_28_64);
|
||||
v_t1_lo = vmull_n_s16(vget_low_s16(v_x1), (int16_t)cospi_12_64);
|
||||
v_t1_hi = vmull_n_s16(vget_high_s16(v_x1), (int16_t)cospi_12_64);
|
||||
v_t1_lo = vmlal_n_s16(v_t1_lo, vget_low_s16(v_x2), (int16_t)cospi_20_64);
|
||||
v_t1_hi = vmlal_n_s16(v_t1_hi, vget_high_s16(v_x2), (int16_t)cospi_20_64);
|
||||
v_t2_lo = vmull_n_s16(vget_low_s16(v_x2), (int16_t)cospi_12_64);
|
||||
v_t2_hi = vmull_n_s16(vget_high_s16(v_x2), (int16_t)cospi_12_64);
|
||||
v_t2_lo = vmlsl_n_s16(v_t2_lo, vget_low_s16(v_x1), (int16_t)cospi_20_64);
|
||||
v_t2_hi = vmlsl_n_s16(v_t2_hi, vget_high_s16(v_x1), (int16_t)cospi_20_64);
|
||||
v_t3_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_28_64);
|
||||
v_t3_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_28_64);
|
||||
v_t3_lo = vmlsl_n_s16(v_t3_lo, vget_low_s16(v_x0), (int16_t)cospi_4_64);
|
||||
v_t3_hi = vmlsl_n_s16(v_t3_hi, vget_high_s16(v_x0), (int16_t)cospi_4_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x4_t e = vrshrn_n_s32(v_t2_lo, DCT_CONST_BITS);
|
||||
const int16x4_t f = vrshrn_n_s32(v_t2_hi, DCT_CONST_BITS);
|
||||
const int16x4_t g = vrshrn_n_s32(v_t3_lo, DCT_CONST_BITS);
|
||||
const int16x4_t h = vrshrn_n_s32(v_t3_hi, DCT_CONST_BITS);
|
||||
out_1 = vcombine_s16(a, c); // 10 11 12 13 50 51 52 53
|
||||
out_3 = vcombine_s16(e, g); // 30 31 32 33 70 71 72 73
|
||||
out_5 = vcombine_s16(b, d); // 14 15 16 17 54 55 56 57
|
||||
out_7 = vcombine_s16(f, h); // 34 35 36 37 74 75 76 77
|
||||
}
|
||||
// transpose 8x8
|
||||
{
|
||||
// 00 01 02 03 40 41 42 43
|
||||
// 10 11 12 13 50 51 52 53
|
||||
// 20 21 22 23 60 61 62 63
|
||||
// 30 31 32 33 70 71 72 73
|
||||
// 04 05 06 07 44 45 46 47
|
||||
// 14 15 16 17 54 55 56 57
|
||||
// 24 25 26 27 64 65 66 67
|
||||
// 34 35 36 37 74 75 76 77
|
||||
const int32x4x2_t r02_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_0),
|
||||
vreinterpretq_s32_s16(out_2));
|
||||
const int32x4x2_t r13_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_1),
|
||||
vreinterpretq_s32_s16(out_3));
|
||||
const int32x4x2_t r46_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_4),
|
||||
vreinterpretq_s32_s16(out_6));
|
||||
const int32x4x2_t r57_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_5),
|
||||
vreinterpretq_s32_s16(out_7));
|
||||
const int16x8x2_t r01_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r02_s32.val[0]),
|
||||
vreinterpretq_s16_s32(r13_s32.val[0]));
|
||||
const int16x8x2_t r23_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r02_s32.val[1]),
|
||||
vreinterpretq_s16_s32(r13_s32.val[1]));
|
||||
const int16x8x2_t r45_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r46_s32.val[0]),
|
||||
vreinterpretq_s16_s32(r57_s32.val[0]));
|
||||
const int16x8x2_t r67_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r46_s32.val[1]),
|
||||
vreinterpretq_s16_s32(r57_s32.val[1]));
|
||||
input_0 = r01_s16.val[0];
|
||||
input_1 = r01_s16.val[1];
|
||||
input_2 = r23_s16.val[0];
|
||||
input_3 = r23_s16.val[1];
|
||||
input_4 = r45_s16.val[0];
|
||||
input_5 = r45_s16.val[1];
|
||||
input_6 = r67_s16.val[0];
|
||||
input_7 = r67_s16.val[1];
|
||||
// 00 10 20 30 40 50 60 70
|
||||
// 01 11 21 31 41 51 61 71
|
||||
// 02 12 22 32 42 52 62 72
|
||||
// 03 13 23 33 43 53 63 73
|
||||
// 04 14 24 34 44 54 64 74
|
||||
// 05 15 25 35 45 55 65 75
|
||||
// 06 16 26 36 46 56 66 76
|
||||
// 07 17 27 37 47 57 67 77
|
||||
}
|
||||
} // for
|
||||
{
|
||||
// from vp9_dct_sse2.c
|
||||
// Post-condition (division by two)
|
||||
// division of two 16 bits signed numbers using shifts
|
||||
// n / 2 = (n - (n >> 15)) >> 1
|
||||
const int16x8_t sign_in0 = vshrq_n_s16(input_0, 15);
|
||||
const int16x8_t sign_in1 = vshrq_n_s16(input_1, 15);
|
||||
const int16x8_t sign_in2 = vshrq_n_s16(input_2, 15);
|
||||
const int16x8_t sign_in3 = vshrq_n_s16(input_3, 15);
|
||||
const int16x8_t sign_in4 = vshrq_n_s16(input_4, 15);
|
||||
const int16x8_t sign_in5 = vshrq_n_s16(input_5, 15);
|
||||
const int16x8_t sign_in6 = vshrq_n_s16(input_6, 15);
|
||||
const int16x8_t sign_in7 = vshrq_n_s16(input_7, 15);
|
||||
input_0 = vhsubq_s16(input_0, sign_in0);
|
||||
input_1 = vhsubq_s16(input_1, sign_in1);
|
||||
input_2 = vhsubq_s16(input_2, sign_in2);
|
||||
input_3 = vhsubq_s16(input_3, sign_in3);
|
||||
input_4 = vhsubq_s16(input_4, sign_in4);
|
||||
input_5 = vhsubq_s16(input_5, sign_in5);
|
||||
input_6 = vhsubq_s16(input_6, sign_in6);
|
||||
input_7 = vhsubq_s16(input_7, sign_in7);
|
||||
// store results
|
||||
vst1q_s16(&final_output[0 * 8], input_0);
|
||||
vst1q_s16(&final_output[1 * 8], input_1);
|
||||
vst1q_s16(&final_output[2 * 8], input_2);
|
||||
vst1q_s16(&final_output[3 * 8], input_3);
|
||||
vst1q_s16(&final_output[4 * 8], input_4);
|
||||
vst1q_s16(&final_output[5 * 8], input_5);
|
||||
vst1q_s16(&final_output[6 * 8], input_6);
|
||||
vst1q_s16(&final_output[7 * 8], input_7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,20 +13,14 @@
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vp9/common/vp9_blockd.h"
|
||||
#include "vp9/common/vp9_idct.h"
|
||||
#include "vp9/common/vp9_systemdependent.h"
|
||||
#include "vp9/encoder/vp9_dct.h"
|
||||
|
||||
static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
|
||||
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
|
||||
// TODO(debargha, peter.derivaz): Find new bounds for this assert
|
||||
// and make the bounds consts.
|
||||
// assert(INT16_MIN <= rv && rv <= INT16_MAX);
|
||||
return rv;
|
||||
}
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_dsp/fwd_txfm.h"
|
||||
|
||||
static void fdct4(const tran_low_t *input, tran_low_t *output) {
|
||||
tran_high_t step[4];
|
||||
@ -546,73 +540,6 @@ void vp9_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
output[1] = 0;
|
||||
}
|
||||
|
||||
void vp9_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
// The 2D transform is done with two passes which are actually pretty
|
||||
// similar. In the first one, we transform the columns and transpose
|
||||
// the results. In the second one, we transform the rows. To achieve that,
|
||||
// as the first pass results are transposed, we transpose the columns (that
|
||||
// is the transposed rows) and transpose the results (so that it goes back
|
||||
// in normal/row positions).
|
||||
int pass;
|
||||
// We need an intermediate buffer between passes.
|
||||
tran_low_t intermediate[4 * 4];
|
||||
const int16_t *in_pass0 = input;
|
||||
const tran_low_t *in = NULL;
|
||||
tran_low_t *out = intermediate;
|
||||
// Do the two transform/transpose passes
|
||||
for (pass = 0; pass < 2; ++pass) {
|
||||
tran_high_t input[4]; // canbe16
|
||||
tran_high_t step[4]; // canbe16
|
||||
tran_high_t temp1, temp2; // needs32
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
// Load inputs.
|
||||
if (0 == pass) {
|
||||
input[0] = in_pass0[0 * stride] * 16;
|
||||
input[1] = in_pass0[1 * stride] * 16;
|
||||
input[2] = in_pass0[2 * stride] * 16;
|
||||
input[3] = in_pass0[3 * stride] * 16;
|
||||
if (i == 0 && input[0]) {
|
||||
input[0] += 1;
|
||||
}
|
||||
} else {
|
||||
input[0] = in[0 * 4];
|
||||
input[1] = in[1 * 4];
|
||||
input[2] = in[2 * 4];
|
||||
input[3] = in[3 * 4];
|
||||
}
|
||||
// Transform.
|
||||
step[0] = input[0] + input[3];
|
||||
step[1] = input[1] + input[2];
|
||||
step[2] = input[1] - input[2];
|
||||
step[3] = input[0] - input[3];
|
||||
temp1 = (step[0] + step[1]) * cospi_16_64;
|
||||
temp2 = (step[0] - step[1]) * cospi_16_64;
|
||||
out[0] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[2] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
|
||||
temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
|
||||
out[1] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[3] = (tran_low_t)fdct_round_shift(temp2);
|
||||
// Do next column (which is a transposed row in second/horizontal pass)
|
||||
in_pass0++;
|
||||
in++;
|
||||
out += 4;
|
||||
}
|
||||
// Setup in/out for next pass.
|
||||
in = intermediate;
|
||||
out = output;
|
||||
}
|
||||
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j)
|
||||
output[j + i * 4] = (output[j + i * 4] + 1) >> 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_fht4x4_c(const int16_t *input, tran_low_t *output,
|
||||
int stride, int tx_type) {
|
||||
if (tx_type == DCT_DCT) {
|
||||
@ -656,77 +583,6 @@ void vp9_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
output[1] = 0;
|
||||
}
|
||||
|
||||
void vp9_fdct8x8_c(const int16_t *input, tran_low_t *final_output, int stride) {
|
||||
int i, j;
|
||||
tran_low_t intermediate[64];
|
||||
|
||||
// Transform columns
|
||||
{
|
||||
tran_low_t *output = intermediate;
|
||||
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
|
||||
tran_high_t t0, t1, t2, t3; // needs32
|
||||
tran_high_t x0, x1, x2, x3; // canbe16
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
// stage 1
|
||||
s0 = (input[0 * stride] + input[7 * stride]) * 4;
|
||||
s1 = (input[1 * stride] + input[6 * stride]) * 4;
|
||||
s2 = (input[2 * stride] + input[5 * stride]) * 4;
|
||||
s3 = (input[3 * stride] + input[4 * stride]) * 4;
|
||||
s4 = (input[3 * stride] - input[4 * stride]) * 4;
|
||||
s5 = (input[2 * stride] - input[5 * stride]) * 4;
|
||||
s6 = (input[1 * stride] - input[6 * stride]) * 4;
|
||||
s7 = (input[0 * stride] - input[7 * stride]) * 4;
|
||||
|
||||
// fdct4(step, step);
|
||||
x0 = s0 + s3;
|
||||
x1 = s1 + s2;
|
||||
x2 = s1 - s2;
|
||||
x3 = s0 - s3;
|
||||
t0 = (x0 + x1) * cospi_16_64;
|
||||
t1 = (x0 - x1) * cospi_16_64;
|
||||
t2 = x2 * cospi_24_64 + x3 * cospi_8_64;
|
||||
t3 = -x2 * cospi_8_64 + x3 * cospi_24_64;
|
||||
output[0 * 8] = (tran_low_t)fdct_round_shift(t0);
|
||||
output[2 * 8] = (tran_low_t)fdct_round_shift(t2);
|
||||
output[4 * 8] = (tran_low_t)fdct_round_shift(t1);
|
||||
output[6 * 8] = (tran_low_t)fdct_round_shift(t3);
|
||||
|
||||
// Stage 2
|
||||
t0 = (s6 - s5) * cospi_16_64;
|
||||
t1 = (s6 + s5) * cospi_16_64;
|
||||
t2 = fdct_round_shift(t0);
|
||||
t3 = fdct_round_shift(t1);
|
||||
|
||||
// Stage 3
|
||||
x0 = s4 + t2;
|
||||
x1 = s4 - t2;
|
||||
x2 = s7 - t3;
|
||||
x3 = s7 + t3;
|
||||
|
||||
// Stage 4
|
||||
t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
|
||||
t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
|
||||
t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
|
||||
t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
|
||||
output[1 * 8] = (tran_low_t)fdct_round_shift(t0);
|
||||
output[3 * 8] = (tran_low_t)fdct_round_shift(t2);
|
||||
output[5 * 8] = (tran_low_t)fdct_round_shift(t1);
|
||||
output[7 * 8] = (tran_low_t)fdct_round_shift(t3);
|
||||
input++;
|
||||
output++;
|
||||
}
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 8; ++i) {
|
||||
fdct8(&intermediate[i * 8], &final_output[i * 8]);
|
||||
for (j = 0; j < 8; ++j)
|
||||
final_output[j + i * 8] /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_fdct8x8_quant_c(const int16_t *input, int stride,
|
||||
tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block,
|
||||
@ -850,186 +706,6 @@ void vp9_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
output[1] = 0;
|
||||
}
|
||||
|
||||
void vp9_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
// The 2D transform is done with two passes which are actually pretty
|
||||
// similar. In the first one, we transform the columns and transpose
|
||||
// the results. In the second one, we transform the rows. To achieve that,
|
||||
// as the first pass results are transposed, we transpose the columns (that
|
||||
// is the transposed rows) and transpose the results (so that it goes back
|
||||
// in normal/row positions).
|
||||
int pass;
|
||||
// We need an intermediate buffer between passes.
|
||||
tran_low_t intermediate[256];
|
||||
const int16_t *in_pass0 = input;
|
||||
const tran_low_t *in = NULL;
|
||||
tran_low_t *out = intermediate;
|
||||
// Do the two transform/transpose passes
|
||||
for (pass = 0; pass < 2; ++pass) {
|
||||
tran_high_t step1[8]; // canbe16
|
||||
tran_high_t step2[8]; // canbe16
|
||||
tran_high_t step3[8]; // canbe16
|
||||
tran_high_t input[8]; // canbe16
|
||||
tran_high_t temp1, temp2; // needs32
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (0 == pass) {
|
||||
// Calculate input for the first 8 results.
|
||||
input[0] = (in_pass0[0 * stride] + in_pass0[15 * stride]) * 4;
|
||||
input[1] = (in_pass0[1 * stride] + in_pass0[14 * stride]) * 4;
|
||||
input[2] = (in_pass0[2 * stride] + in_pass0[13 * stride]) * 4;
|
||||
input[3] = (in_pass0[3 * stride] + in_pass0[12 * stride]) * 4;
|
||||
input[4] = (in_pass0[4 * stride] + in_pass0[11 * stride]) * 4;
|
||||
input[5] = (in_pass0[5 * stride] + in_pass0[10 * stride]) * 4;
|
||||
input[6] = (in_pass0[6 * stride] + in_pass0[ 9 * stride]) * 4;
|
||||
input[7] = (in_pass0[7 * stride] + in_pass0[ 8 * stride]) * 4;
|
||||
// Calculate input for the next 8 results.
|
||||
step1[0] = (in_pass0[7 * stride] - in_pass0[ 8 * stride]) * 4;
|
||||
step1[1] = (in_pass0[6 * stride] - in_pass0[ 9 * stride]) * 4;
|
||||
step1[2] = (in_pass0[5 * stride] - in_pass0[10 * stride]) * 4;
|
||||
step1[3] = (in_pass0[4 * stride] - in_pass0[11 * stride]) * 4;
|
||||
step1[4] = (in_pass0[3 * stride] - in_pass0[12 * stride]) * 4;
|
||||
step1[5] = (in_pass0[2 * stride] - in_pass0[13 * stride]) * 4;
|
||||
step1[6] = (in_pass0[1 * stride] - in_pass0[14 * stride]) * 4;
|
||||
step1[7] = (in_pass0[0 * stride] - in_pass0[15 * stride]) * 4;
|
||||
} else {
|
||||
// Calculate input for the first 8 results.
|
||||
input[0] = ((in[0 * 16] + 1) >> 2) + ((in[15 * 16] + 1) >> 2);
|
||||
input[1] = ((in[1 * 16] + 1) >> 2) + ((in[14 * 16] + 1) >> 2);
|
||||
input[2] = ((in[2 * 16] + 1) >> 2) + ((in[13 * 16] + 1) >> 2);
|
||||
input[3] = ((in[3 * 16] + 1) >> 2) + ((in[12 * 16] + 1) >> 2);
|
||||
input[4] = ((in[4 * 16] + 1) >> 2) + ((in[11 * 16] + 1) >> 2);
|
||||
input[5] = ((in[5 * 16] + 1) >> 2) + ((in[10 * 16] + 1) >> 2);
|
||||
input[6] = ((in[6 * 16] + 1) >> 2) + ((in[ 9 * 16] + 1) >> 2);
|
||||
input[7] = ((in[7 * 16] + 1) >> 2) + ((in[ 8 * 16] + 1) >> 2);
|
||||
// Calculate input for the next 8 results.
|
||||
step1[0] = ((in[7 * 16] + 1) >> 2) - ((in[ 8 * 16] + 1) >> 2);
|
||||
step1[1] = ((in[6 * 16] + 1) >> 2) - ((in[ 9 * 16] + 1) >> 2);
|
||||
step1[2] = ((in[5 * 16] + 1) >> 2) - ((in[10 * 16] + 1) >> 2);
|
||||
step1[3] = ((in[4 * 16] + 1) >> 2) - ((in[11 * 16] + 1) >> 2);
|
||||
step1[4] = ((in[3 * 16] + 1) >> 2) - ((in[12 * 16] + 1) >> 2);
|
||||
step1[5] = ((in[2 * 16] + 1) >> 2) - ((in[13 * 16] + 1) >> 2);
|
||||
step1[6] = ((in[1 * 16] + 1) >> 2) - ((in[14 * 16] + 1) >> 2);
|
||||
step1[7] = ((in[0 * 16] + 1) >> 2) - ((in[15 * 16] + 1) >> 2);
|
||||
}
|
||||
// Work on the first eight values; fdct8(input, even_results);
|
||||
{
|
||||
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
|
||||
tran_high_t t0, t1, t2, t3; // needs32
|
||||
tran_high_t x0, x1, x2, x3; // canbe16
|
||||
|
||||
// stage 1
|
||||
s0 = input[0] + input[7];
|
||||
s1 = input[1] + input[6];
|
||||
s2 = input[2] + input[5];
|
||||
s3 = input[3] + input[4];
|
||||
s4 = input[3] - input[4];
|
||||
s5 = input[2] - input[5];
|
||||
s6 = input[1] - input[6];
|
||||
s7 = input[0] - input[7];
|
||||
|
||||
// fdct4(step, step);
|
||||
x0 = s0 + s3;
|
||||
x1 = s1 + s2;
|
||||
x2 = s1 - s2;
|
||||
x3 = s0 - s3;
|
||||
t0 = (x0 + x1) * cospi_16_64;
|
||||
t1 = (x0 - x1) * cospi_16_64;
|
||||
t2 = x3 * cospi_8_64 + x2 * cospi_24_64;
|
||||
t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
|
||||
out[0] = (tran_low_t)fdct_round_shift(t0);
|
||||
out[4] = (tran_low_t)fdct_round_shift(t2);
|
||||
out[8] = (tran_low_t)fdct_round_shift(t1);
|
||||
out[12] = (tran_low_t)fdct_round_shift(t3);
|
||||
|
||||
// Stage 2
|
||||
t0 = (s6 - s5) * cospi_16_64;
|
||||
t1 = (s6 + s5) * cospi_16_64;
|
||||
t2 = fdct_round_shift(t0);
|
||||
t3 = fdct_round_shift(t1);
|
||||
|
||||
// Stage 3
|
||||
x0 = s4 + t2;
|
||||
x1 = s4 - t2;
|
||||
x2 = s7 - t3;
|
||||
x3 = s7 + t3;
|
||||
|
||||
// Stage 4
|
||||
t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
|
||||
t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
|
||||
t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
|
||||
t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
|
||||
out[2] = (tran_low_t)fdct_round_shift(t0);
|
||||
out[6] = (tran_low_t)fdct_round_shift(t2);
|
||||
out[10] = (tran_low_t)fdct_round_shift(t1);
|
||||
out[14] = (tran_low_t)fdct_round_shift(t3);
|
||||
}
|
||||
// Work on the next eight values; step1 -> odd_results
|
||||
{
|
||||
// step 2
|
||||
temp1 = (step1[5] - step1[2]) * cospi_16_64;
|
||||
temp2 = (step1[4] - step1[3]) * cospi_16_64;
|
||||
step2[2] = fdct_round_shift(temp1);
|
||||
step2[3] = fdct_round_shift(temp2);
|
||||
temp1 = (step1[4] + step1[3]) * cospi_16_64;
|
||||
temp2 = (step1[5] + step1[2]) * cospi_16_64;
|
||||
step2[4] = fdct_round_shift(temp1);
|
||||
step2[5] = fdct_round_shift(temp2);
|
||||
// step 3
|
||||
step3[0] = step1[0] + step2[3];
|
||||
step3[1] = step1[1] + step2[2];
|
||||
step3[2] = step1[1] - step2[2];
|
||||
step3[3] = step1[0] - step2[3];
|
||||
step3[4] = step1[7] - step2[4];
|
||||
step3[5] = step1[6] - step2[5];
|
||||
step3[6] = step1[6] + step2[5];
|
||||
step3[7] = step1[7] + step2[4];
|
||||
// step 4
|
||||
temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64;
|
||||
temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64;
|
||||
step2[1] = fdct_round_shift(temp1);
|
||||
step2[2] = fdct_round_shift(temp2);
|
||||
temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64;
|
||||
temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64;
|
||||
step2[5] = fdct_round_shift(temp1);
|
||||
step2[6] = fdct_round_shift(temp2);
|
||||
// step 5
|
||||
step1[0] = step3[0] + step2[1];
|
||||
step1[1] = step3[0] - step2[1];
|
||||
step1[2] = step3[3] + step2[2];
|
||||
step1[3] = step3[3] - step2[2];
|
||||
step1[4] = step3[4] - step2[5];
|
||||
step1[5] = step3[4] + step2[5];
|
||||
step1[6] = step3[7] - step2[6];
|
||||
step1[7] = step3[7] + step2[6];
|
||||
// step 6
|
||||
temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64;
|
||||
temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
|
||||
out[1] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[9] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
|
||||
temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64;
|
||||
out[5] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[13] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64;
|
||||
temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
|
||||
out[3] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[11] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
|
||||
temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64;
|
||||
out[7] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[15] = (tran_low_t)fdct_round_shift(temp2);
|
||||
}
|
||||
// Do next column (which is a transposed row in second/horizontal pass)
|
||||
in++;
|
||||
in_pass0++;
|
||||
out += 16;
|
||||
}
|
||||
// Setup in/out for next pass.
|
||||
in = intermediate;
|
||||
out = output;
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_fht8x8_c(const int16_t *input, tran_low_t *output,
|
||||
int stride, int tx_type) {
|
||||
if (tx_type == DCT_DCT) {
|
||||
@ -1551,11 +1227,6 @@ void vp9_fdct32x32_rd_c(const int16_t *input, tran_low_t *out, int stride) {
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void vp9_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
vp9_fdct4x4_c(input, output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fht4x4_c(const int16_t *input, tran_low_t *output,
|
||||
int stride, int tx_type) {
|
||||
vp9_fht4x4_c(input, output, stride, tx_type);
|
||||
@ -1566,21 +1237,11 @@ void vp9_highbd_fdct8x8_1_c(const int16_t *input, tran_low_t *final_output,
|
||||
vp9_fdct8x8_1_c(input, final_output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fdct8x8_c(const int16_t *input, tran_low_t *final_output,
|
||||
int stride) {
|
||||
vp9_fdct8x8_c(input, final_output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fdct16x16_1_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
vp9_fdct16x16_1_c(input, output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
vp9_fdct16x16_c(input, output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fht8x8_c(const int16_t *input, tran_low_t *output,
|
||||
int stride, int tx_type) {
|
||||
vp9_fht8x8_c(input, output, stride, tx_type);
|
||||
|
@ -2275,14 +2275,6 @@ void vp9_fdct32x32_1_sse2(const int16_t *input, tran_low_t *output,
|
||||
|
||||
#define DCT_HIGH_BIT_DEPTH 0
|
||||
|
||||
#define FDCT4x4_2D vp9_fdct4x4_sse2
|
||||
#define FDCT8x8_2D vp9_fdct8x8_sse2
|
||||
#define FDCT16x16_2D vp9_fdct16x16_sse2
|
||||
#include "vp9/encoder/x86/vp9_dct_sse2_impl.h"
|
||||
#undef FDCT4x4_2D
|
||||
#undef FDCT8x8_2D
|
||||
#undef FDCT16x16_2D
|
||||
|
||||
#define FDCT32x32_2D vp9_fdct32x32_rd_sse2
|
||||
#define FDCT32x32_HIGH_PRECISION 0
|
||||
#include "vp9/encoder/x86/vp9_dct32x32_sse2_impl.h"
|
||||
@ -2302,14 +2294,6 @@ void vp9_fdct32x32_1_sse2(const int16_t *input, tran_low_t *output,
|
||||
|
||||
#define DCT_HIGH_BIT_DEPTH 1
|
||||
|
||||
#define FDCT4x4_2D vp9_highbd_fdct4x4_sse2
|
||||
#define FDCT8x8_2D vp9_highbd_fdct8x8_sse2
|
||||
#define FDCT16x16_2D vp9_highbd_fdct16x16_sse2
|
||||
#include "vp9/encoder/x86/vp9_dct_sse2_impl.h" // NOLINT
|
||||
#undef FDCT4x4_2D
|
||||
#undef FDCT8x8_2D
|
||||
#undef FDCT16x16_2D
|
||||
|
||||
#define FDCT32x32_2D vp9_highbd_fdct32x32_rd_sse2
|
||||
#define FDCT32x32_HIGH_PRECISION 0
|
||||
#include "vp9/encoder/x86/vp9_dct32x32_sse2_impl.h" // NOLINT
|
||||
|
@ -13,49 +13,9 @@
|
||||
; of the macro definitions are originally derived from the ffmpeg project.
|
||||
; The current version applies to x86 64-bit only.
|
||||
|
||||
SECTION_RODATA
|
||||
|
||||
pw_11585x2: times 8 dw 23170
|
||||
pd_8192: times 4 dd 8192
|
||||
|
||||
%macro TRANSFORM_COEFFS 2
|
||||
pw_%1_%2: dw %1, %2, %1, %2, %1, %2, %1, %2
|
||||
pw_%2_m%1: dw %2, -%1, %2, -%1, %2, -%1, %2, -%1
|
||||
%endmacro
|
||||
|
||||
TRANSFORM_COEFFS 11585, 11585
|
||||
TRANSFORM_COEFFS 15137, 6270
|
||||
TRANSFORM_COEFFS 16069, 3196
|
||||
TRANSFORM_COEFFS 9102, 13623
|
||||
|
||||
SECTION .text
|
||||
|
||||
%if ARCH_X86_64
|
||||
%macro SUM_SUB 3
|
||||
psubw m%3, m%1, m%2
|
||||
paddw m%1, m%2
|
||||
SWAP %2, %3
|
||||
%endmacro
|
||||
|
||||
; butterfly operation
|
||||
%macro MUL_ADD_2X 6 ; dst1, dst2, src, round, coefs1, coefs2
|
||||
pmaddwd m%1, m%3, %5
|
||||
pmaddwd m%2, m%3, %6
|
||||
paddd m%1, %4
|
||||
paddd m%2, %4
|
||||
psrad m%1, 14
|
||||
psrad m%2, 14
|
||||
%endmacro
|
||||
|
||||
%macro BUTTERFLY_4X 7 ; dst1, dst2, coef1, coef2, round, tmp1, tmp2
|
||||
punpckhwd m%6, m%2, m%1
|
||||
MUL_ADD_2X %7, %6, %6, %5, [pw_%4_%3], [pw_%3_m%4]
|
||||
punpcklwd m%2, m%1
|
||||
MUL_ADD_2X %1, %2, %2, %5, [pw_%4_%3], [pw_%3_m%4]
|
||||
packssdw m%1, m%7
|
||||
packssdw m%2, m%6
|
||||
%endmacro
|
||||
|
||||
; matrix transpose
|
||||
%macro INTERLEAVE_2X 4
|
||||
punpckh%1 m%4, m%2, m%3
|
||||
@ -83,103 +43,6 @@ SECTION .text
|
||||
SWAP %4, %7
|
||||
%endmacro
|
||||
|
||||
; 1D forward 8x8 DCT transform
|
||||
%macro FDCT8_1D 1
|
||||
SUM_SUB 0, 7, 9
|
||||
SUM_SUB 1, 6, 9
|
||||
SUM_SUB 2, 5, 9
|
||||
SUM_SUB 3, 4, 9
|
||||
|
||||
SUM_SUB 0, 3, 9
|
||||
SUM_SUB 1, 2, 9
|
||||
SUM_SUB 6, 5, 9
|
||||
%if %1 == 0
|
||||
SUM_SUB 0, 1, 9
|
||||
%endif
|
||||
|
||||
BUTTERFLY_4X 2, 3, 6270, 15137, m8, 9, 10
|
||||
|
||||
pmulhrsw m6, m12
|
||||
pmulhrsw m5, m12
|
||||
%if %1 == 0
|
||||
pmulhrsw m0, m12
|
||||
pmulhrsw m1, m12
|
||||
%else
|
||||
BUTTERFLY_4X 1, 0, 11585, 11585, m8, 9, 10
|
||||
SWAP 0, 1
|
||||
%endif
|
||||
|
||||
SUM_SUB 4, 5, 9
|
||||
SUM_SUB 7, 6, 9
|
||||
BUTTERFLY_4X 4, 7, 3196, 16069, m8, 9, 10
|
||||
BUTTERFLY_4X 5, 6, 13623, 9102, m8, 9, 10
|
||||
SWAP 1, 4
|
||||
SWAP 3, 6
|
||||
%endmacro
|
||||
|
||||
%macro DIVIDE_ROUND_2X 4 ; dst1, dst2, tmp1, tmp2
|
||||
psraw m%3, m%1, 15
|
||||
psraw m%4, m%2, 15
|
||||
psubw m%1, m%3
|
||||
psubw m%2, m%4
|
||||
psraw m%1, 1
|
||||
psraw m%2, 1
|
||||
%endmacro
|
||||
|
||||
INIT_XMM ssse3
|
||||
cglobal fdct8x8, 3, 5, 13, input, output, stride
|
||||
|
||||
mova m8, [pd_8192]
|
||||
mova m12, [pw_11585x2]
|
||||
pxor m11, m11
|
||||
|
||||
lea r3, [2 * strideq]
|
||||
lea r4, [4 * strideq]
|
||||
mova m0, [inputq]
|
||||
mova m1, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m2, [inputq]
|
||||
mova m3, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m4, [inputq]
|
||||
mova m5, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m6, [inputq]
|
||||
mova m7, [inputq + r3]
|
||||
|
||||
; left shift by 2 to increase forward transformation precision
|
||||
psllw m0, 2
|
||||
psllw m1, 2
|
||||
psllw m2, 2
|
||||
psllw m3, 2
|
||||
psllw m4, 2
|
||||
psllw m5, 2
|
||||
psllw m6, 2
|
||||
psllw m7, 2
|
||||
|
||||
; column transform
|
||||
FDCT8_1D 0
|
||||
TRANSPOSE8X8 0, 1, 2, 3, 4, 5, 6, 7, 9
|
||||
|
||||
FDCT8_1D 1
|
||||
TRANSPOSE8X8 0, 1, 2, 3, 4, 5, 6, 7, 9
|
||||
|
||||
DIVIDE_ROUND_2X 0, 1, 9, 10
|
||||
DIVIDE_ROUND_2X 2, 3, 9, 10
|
||||
DIVIDE_ROUND_2X 4, 5, 9, 10
|
||||
DIVIDE_ROUND_2X 6, 7, 9, 10
|
||||
|
||||
mova [outputq + 0], m0
|
||||
mova [outputq + 16], m1
|
||||
mova [outputq + 32], m2
|
||||
mova [outputq + 48], m3
|
||||
mova [outputq + 64], m4
|
||||
mova [outputq + 80], m5
|
||||
mova [outputq + 96], m6
|
||||
mova [outputq + 112], m7
|
||||
|
||||
RET
|
||||
|
||||
%macro HMD8_1D 0
|
||||
psubw m8, m0, m1
|
||||
psubw m9, m2, m3
|
||||
|
@ -120,7 +120,6 @@ VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct_sse2.c
|
||||
VP9_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/vp9_dct_ssse3.c
|
||||
VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct_sse2.h
|
||||
VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct32x32_sse2_impl.h
|
||||
VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct_sse2_impl.h
|
||||
|
||||
ifeq ($(CONFIG_VP9_TEMPORAL_DENOISING),yes)
|
||||
VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_denoiser_sse2.c
|
||||
|
202
vpx_dsp/arm/fwd_txfm_neon.c
Normal file
202
vpx_dsp/arm/fwd_txfm_neon.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include "./vpx_config.h"
|
||||
#include "vp9/common/vp9_idct.h"
|
||||
|
||||
void vp9_fdct8x8_neon(const int16_t *input, int16_t *final_output, int stride) {
|
||||
int i;
|
||||
// stage 1
|
||||
int16x8_t input_0 = vshlq_n_s16(vld1q_s16(&input[0 * stride]), 2);
|
||||
int16x8_t input_1 = vshlq_n_s16(vld1q_s16(&input[1 * stride]), 2);
|
||||
int16x8_t input_2 = vshlq_n_s16(vld1q_s16(&input[2 * stride]), 2);
|
||||
int16x8_t input_3 = vshlq_n_s16(vld1q_s16(&input[3 * stride]), 2);
|
||||
int16x8_t input_4 = vshlq_n_s16(vld1q_s16(&input[4 * stride]), 2);
|
||||
int16x8_t input_5 = vshlq_n_s16(vld1q_s16(&input[5 * stride]), 2);
|
||||
int16x8_t input_6 = vshlq_n_s16(vld1q_s16(&input[6 * stride]), 2);
|
||||
int16x8_t input_7 = vshlq_n_s16(vld1q_s16(&input[7 * stride]), 2);
|
||||
for (i = 0; i < 2; ++i) {
|
||||
int16x8_t out_0, out_1, out_2, out_3, out_4, out_5, out_6, out_7;
|
||||
const int16x8_t v_s0 = vaddq_s16(input_0, input_7);
|
||||
const int16x8_t v_s1 = vaddq_s16(input_1, input_6);
|
||||
const int16x8_t v_s2 = vaddq_s16(input_2, input_5);
|
||||
const int16x8_t v_s3 = vaddq_s16(input_3, input_4);
|
||||
const int16x8_t v_s4 = vsubq_s16(input_3, input_4);
|
||||
const int16x8_t v_s5 = vsubq_s16(input_2, input_5);
|
||||
const int16x8_t v_s6 = vsubq_s16(input_1, input_6);
|
||||
const int16x8_t v_s7 = vsubq_s16(input_0, input_7);
|
||||
// fdct4(step, step);
|
||||
int16x8_t v_x0 = vaddq_s16(v_s0, v_s3);
|
||||
int16x8_t v_x1 = vaddq_s16(v_s1, v_s2);
|
||||
int16x8_t v_x2 = vsubq_s16(v_s1, v_s2);
|
||||
int16x8_t v_x3 = vsubq_s16(v_s0, v_s3);
|
||||
// fdct4(step, step);
|
||||
int32x4_t v_t0_lo = vaddl_s16(vget_low_s16(v_x0), vget_low_s16(v_x1));
|
||||
int32x4_t v_t0_hi = vaddl_s16(vget_high_s16(v_x0), vget_high_s16(v_x1));
|
||||
int32x4_t v_t1_lo = vsubl_s16(vget_low_s16(v_x0), vget_low_s16(v_x1));
|
||||
int32x4_t v_t1_hi = vsubl_s16(vget_high_s16(v_x0), vget_high_s16(v_x1));
|
||||
int32x4_t v_t2_lo = vmull_n_s16(vget_low_s16(v_x2), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t2_hi = vmull_n_s16(vget_high_s16(v_x2), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t3_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_24_64);
|
||||
int32x4_t v_t3_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_24_64);
|
||||
v_t2_lo = vmlal_n_s16(v_t2_lo, vget_low_s16(v_x3), (int16_t)cospi_8_64);
|
||||
v_t2_hi = vmlal_n_s16(v_t2_hi, vget_high_s16(v_x3), (int16_t)cospi_8_64);
|
||||
v_t3_lo = vmlsl_n_s16(v_t3_lo, vget_low_s16(v_x2), (int16_t)cospi_8_64);
|
||||
v_t3_hi = vmlsl_n_s16(v_t3_hi, vget_high_s16(v_x2), (int16_t)cospi_8_64);
|
||||
v_t0_lo = vmulq_n_s32(v_t0_lo, cospi_16_64);
|
||||
v_t0_hi = vmulq_n_s32(v_t0_hi, cospi_16_64);
|
||||
v_t1_lo = vmulq_n_s32(v_t1_lo, cospi_16_64);
|
||||
v_t1_hi = vmulq_n_s32(v_t1_hi, cospi_16_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x4_t e = vrshrn_n_s32(v_t2_lo, DCT_CONST_BITS);
|
||||
const int16x4_t f = vrshrn_n_s32(v_t2_hi, DCT_CONST_BITS);
|
||||
const int16x4_t g = vrshrn_n_s32(v_t3_lo, DCT_CONST_BITS);
|
||||
const int16x4_t h = vrshrn_n_s32(v_t3_hi, DCT_CONST_BITS);
|
||||
out_0 = vcombine_s16(a, c); // 00 01 02 03 40 41 42 43
|
||||
out_2 = vcombine_s16(e, g); // 20 21 22 23 60 61 62 63
|
||||
out_4 = vcombine_s16(b, d); // 04 05 06 07 44 45 46 47
|
||||
out_6 = vcombine_s16(f, h); // 24 25 26 27 64 65 66 67
|
||||
}
|
||||
// Stage 2
|
||||
v_x0 = vsubq_s16(v_s6, v_s5);
|
||||
v_x1 = vaddq_s16(v_s6, v_s5);
|
||||
v_t0_lo = vmull_n_s16(vget_low_s16(v_x0), (int16_t)cospi_16_64);
|
||||
v_t0_hi = vmull_n_s16(vget_high_s16(v_x0), (int16_t)cospi_16_64);
|
||||
v_t1_lo = vmull_n_s16(vget_low_s16(v_x1), (int16_t)cospi_16_64);
|
||||
v_t1_hi = vmull_n_s16(vget_high_s16(v_x1), (int16_t)cospi_16_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x8_t ab = vcombine_s16(a, b);
|
||||
const int16x8_t cd = vcombine_s16(c, d);
|
||||
// Stage 3
|
||||
v_x0 = vaddq_s16(v_s4, ab);
|
||||
v_x1 = vsubq_s16(v_s4, ab);
|
||||
v_x2 = vsubq_s16(v_s7, cd);
|
||||
v_x3 = vaddq_s16(v_s7, cd);
|
||||
}
|
||||
// Stage 4
|
||||
v_t0_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_4_64);
|
||||
v_t0_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_4_64);
|
||||
v_t0_lo = vmlal_n_s16(v_t0_lo, vget_low_s16(v_x0), (int16_t)cospi_28_64);
|
||||
v_t0_hi = vmlal_n_s16(v_t0_hi, vget_high_s16(v_x0), (int16_t)cospi_28_64);
|
||||
v_t1_lo = vmull_n_s16(vget_low_s16(v_x1), (int16_t)cospi_12_64);
|
||||
v_t1_hi = vmull_n_s16(vget_high_s16(v_x1), (int16_t)cospi_12_64);
|
||||
v_t1_lo = vmlal_n_s16(v_t1_lo, vget_low_s16(v_x2), (int16_t)cospi_20_64);
|
||||
v_t1_hi = vmlal_n_s16(v_t1_hi, vget_high_s16(v_x2), (int16_t)cospi_20_64);
|
||||
v_t2_lo = vmull_n_s16(vget_low_s16(v_x2), (int16_t)cospi_12_64);
|
||||
v_t2_hi = vmull_n_s16(vget_high_s16(v_x2), (int16_t)cospi_12_64);
|
||||
v_t2_lo = vmlsl_n_s16(v_t2_lo, vget_low_s16(v_x1), (int16_t)cospi_20_64);
|
||||
v_t2_hi = vmlsl_n_s16(v_t2_hi, vget_high_s16(v_x1), (int16_t)cospi_20_64);
|
||||
v_t3_lo = vmull_n_s16(vget_low_s16(v_x3), (int16_t)cospi_28_64);
|
||||
v_t3_hi = vmull_n_s16(vget_high_s16(v_x3), (int16_t)cospi_28_64);
|
||||
v_t3_lo = vmlsl_n_s16(v_t3_lo, vget_low_s16(v_x0), (int16_t)cospi_4_64);
|
||||
v_t3_hi = vmlsl_n_s16(v_t3_hi, vget_high_s16(v_x0), (int16_t)cospi_4_64);
|
||||
{
|
||||
const int16x4_t a = vrshrn_n_s32(v_t0_lo, DCT_CONST_BITS);
|
||||
const int16x4_t b = vrshrn_n_s32(v_t0_hi, DCT_CONST_BITS);
|
||||
const int16x4_t c = vrshrn_n_s32(v_t1_lo, DCT_CONST_BITS);
|
||||
const int16x4_t d = vrshrn_n_s32(v_t1_hi, DCT_CONST_BITS);
|
||||
const int16x4_t e = vrshrn_n_s32(v_t2_lo, DCT_CONST_BITS);
|
||||
const int16x4_t f = vrshrn_n_s32(v_t2_hi, DCT_CONST_BITS);
|
||||
const int16x4_t g = vrshrn_n_s32(v_t3_lo, DCT_CONST_BITS);
|
||||
const int16x4_t h = vrshrn_n_s32(v_t3_hi, DCT_CONST_BITS);
|
||||
out_1 = vcombine_s16(a, c); // 10 11 12 13 50 51 52 53
|
||||
out_3 = vcombine_s16(e, g); // 30 31 32 33 70 71 72 73
|
||||
out_5 = vcombine_s16(b, d); // 14 15 16 17 54 55 56 57
|
||||
out_7 = vcombine_s16(f, h); // 34 35 36 37 74 75 76 77
|
||||
}
|
||||
// transpose 8x8
|
||||
{
|
||||
// 00 01 02 03 40 41 42 43
|
||||
// 10 11 12 13 50 51 52 53
|
||||
// 20 21 22 23 60 61 62 63
|
||||
// 30 31 32 33 70 71 72 73
|
||||
// 04 05 06 07 44 45 46 47
|
||||
// 14 15 16 17 54 55 56 57
|
||||
// 24 25 26 27 64 65 66 67
|
||||
// 34 35 36 37 74 75 76 77
|
||||
const int32x4x2_t r02_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_0),
|
||||
vreinterpretq_s32_s16(out_2));
|
||||
const int32x4x2_t r13_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_1),
|
||||
vreinterpretq_s32_s16(out_3));
|
||||
const int32x4x2_t r46_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_4),
|
||||
vreinterpretq_s32_s16(out_6));
|
||||
const int32x4x2_t r57_s32 = vtrnq_s32(vreinterpretq_s32_s16(out_5),
|
||||
vreinterpretq_s32_s16(out_7));
|
||||
const int16x8x2_t r01_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r02_s32.val[0]),
|
||||
vreinterpretq_s16_s32(r13_s32.val[0]));
|
||||
const int16x8x2_t r23_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r02_s32.val[1]),
|
||||
vreinterpretq_s16_s32(r13_s32.val[1]));
|
||||
const int16x8x2_t r45_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r46_s32.val[0]),
|
||||
vreinterpretq_s16_s32(r57_s32.val[0]));
|
||||
const int16x8x2_t r67_s16 =
|
||||
vtrnq_s16(vreinterpretq_s16_s32(r46_s32.val[1]),
|
||||
vreinterpretq_s16_s32(r57_s32.val[1]));
|
||||
input_0 = r01_s16.val[0];
|
||||
input_1 = r01_s16.val[1];
|
||||
input_2 = r23_s16.val[0];
|
||||
input_3 = r23_s16.val[1];
|
||||
input_4 = r45_s16.val[0];
|
||||
input_5 = r45_s16.val[1];
|
||||
input_6 = r67_s16.val[0];
|
||||
input_7 = r67_s16.val[1];
|
||||
// 00 10 20 30 40 50 60 70
|
||||
// 01 11 21 31 41 51 61 71
|
||||
// 02 12 22 32 42 52 62 72
|
||||
// 03 13 23 33 43 53 63 73
|
||||
// 04 14 24 34 44 54 64 74
|
||||
// 05 15 25 35 45 55 65 75
|
||||
// 06 16 26 36 46 56 66 76
|
||||
// 07 17 27 37 47 57 67 77
|
||||
}
|
||||
} // for
|
||||
{
|
||||
// from vp9_dct_sse2.c
|
||||
// Post-condition (division by two)
|
||||
// division of two 16 bits signed numbers using shifts
|
||||
// n / 2 = (n - (n >> 15)) >> 1
|
||||
const int16x8_t sign_in0 = vshrq_n_s16(input_0, 15);
|
||||
const int16x8_t sign_in1 = vshrq_n_s16(input_1, 15);
|
||||
const int16x8_t sign_in2 = vshrq_n_s16(input_2, 15);
|
||||
const int16x8_t sign_in3 = vshrq_n_s16(input_3, 15);
|
||||
const int16x8_t sign_in4 = vshrq_n_s16(input_4, 15);
|
||||
const int16x8_t sign_in5 = vshrq_n_s16(input_5, 15);
|
||||
const int16x8_t sign_in6 = vshrq_n_s16(input_6, 15);
|
||||
const int16x8_t sign_in7 = vshrq_n_s16(input_7, 15);
|
||||
input_0 = vhsubq_s16(input_0, sign_in0);
|
||||
input_1 = vhsubq_s16(input_1, sign_in1);
|
||||
input_2 = vhsubq_s16(input_2, sign_in2);
|
||||
input_3 = vhsubq_s16(input_3, sign_in3);
|
||||
input_4 = vhsubq_s16(input_4, sign_in4);
|
||||
input_5 = vhsubq_s16(input_5, sign_in5);
|
||||
input_6 = vhsubq_s16(input_6, sign_in6);
|
||||
input_7 = vhsubq_s16(input_7, sign_in7);
|
||||
// store results
|
||||
vst1q_s16(&final_output[0 * 8], input_0);
|
||||
vst1q_s16(&final_output[1 * 8], input_1);
|
||||
vst1q_s16(&final_output[2 * 8], input_2);
|
||||
vst1q_s16(&final_output[3 * 8], input_3);
|
||||
vst1q_s16(&final_output[4 * 8], input_4);
|
||||
vst1q_s16(&final_output[5 * 8], input_5);
|
||||
vst1q_s16(&final_output[6 * 8], input_6);
|
||||
vst1q_s16(&final_output[7 * 8], input_7);
|
||||
}
|
||||
}
|
361
vpx_dsp/fwd_txfm.c
Normal file
361
vpx_dsp/fwd_txfm.c
Normal file
@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "vpx_dsp/fwd_txfm.h"
|
||||
|
||||
void vp9_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
// The 2D transform is done with two passes which are actually pretty
|
||||
// similar. In the first one, we transform the columns and transpose
|
||||
// the results. In the second one, we transform the rows. To achieve that,
|
||||
// as the first pass results are transposed, we transpose the columns (that
|
||||
// is the transposed rows) and transpose the results (so that it goes back
|
||||
// in normal/row positions).
|
||||
int pass;
|
||||
// We need an intermediate buffer between passes.
|
||||
tran_low_t intermediate[4 * 4];
|
||||
const int16_t *in_pass0 = input;
|
||||
const tran_low_t *in = NULL;
|
||||
tran_low_t *out = intermediate;
|
||||
// Do the two transform/transpose passes
|
||||
for (pass = 0; pass < 2; ++pass) {
|
||||
tran_high_t input[4]; // canbe16
|
||||
tran_high_t step[4]; // canbe16
|
||||
tran_high_t temp1, temp2; // needs32
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
// Load inputs.
|
||||
if (0 == pass) {
|
||||
input[0] = in_pass0[0 * stride] * 16;
|
||||
input[1] = in_pass0[1 * stride] * 16;
|
||||
input[2] = in_pass0[2 * stride] * 16;
|
||||
input[3] = in_pass0[3 * stride] * 16;
|
||||
if (i == 0 && input[0]) {
|
||||
input[0] += 1;
|
||||
}
|
||||
} else {
|
||||
input[0] = in[0 * 4];
|
||||
input[1] = in[1 * 4];
|
||||
input[2] = in[2 * 4];
|
||||
input[3] = in[3 * 4];
|
||||
}
|
||||
// Transform.
|
||||
step[0] = input[0] + input[3];
|
||||
step[1] = input[1] + input[2];
|
||||
step[2] = input[1] - input[2];
|
||||
step[3] = input[0] - input[3];
|
||||
temp1 = (step[0] + step[1]) * cospi_16_64;
|
||||
temp2 = (step[0] - step[1]) * cospi_16_64;
|
||||
out[0] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[2] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
|
||||
temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
|
||||
out[1] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[3] = (tran_low_t)fdct_round_shift(temp2);
|
||||
// Do next column (which is a transposed row in second/horizontal pass)
|
||||
in_pass0++;
|
||||
in++;
|
||||
out += 4;
|
||||
}
|
||||
// Setup in/out for next pass.
|
||||
in = intermediate;
|
||||
out = output;
|
||||
}
|
||||
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 4; ++j)
|
||||
output[j + i * 4] = (output[j + i * 4] + 1) >> 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_fdct8x8_c(const int16_t *input, tran_low_t *final_output, int stride) {
|
||||
int i, j;
|
||||
tran_low_t intermediate[64];
|
||||
int pass;
|
||||
tran_low_t *output = intermediate;
|
||||
const tran_low_t *in = NULL;
|
||||
|
||||
// Transform columns
|
||||
for (pass = 0; pass < 2; ++pass) {
|
||||
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
|
||||
tran_high_t t0, t1, t2, t3; // needs32
|
||||
tran_high_t x0, x1, x2, x3; // canbe16
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
// stage 1
|
||||
if (pass == 0) {
|
||||
s0 = (input[0 * stride] + input[7 * stride]) * 4;
|
||||
s1 = (input[1 * stride] + input[6 * stride]) * 4;
|
||||
s2 = (input[2 * stride] + input[5 * stride]) * 4;
|
||||
s3 = (input[3 * stride] + input[4 * stride]) * 4;
|
||||
s4 = (input[3 * stride] - input[4 * stride]) * 4;
|
||||
s5 = (input[2 * stride] - input[5 * stride]) * 4;
|
||||
s6 = (input[1 * stride] - input[6 * stride]) * 4;
|
||||
s7 = (input[0 * stride] - input[7 * stride]) * 4;
|
||||
++input;
|
||||
} else {
|
||||
s0 = in[0 * 8] + in[7 * 8];
|
||||
s1 = in[1 * 8] + in[6 * 8];
|
||||
s2 = in[2 * 8] + in[5 * 8];
|
||||
s3 = in[3 * 8] + in[4 * 8];
|
||||
s4 = in[3 * 8] - in[4 * 8];
|
||||
s5 = in[2 * 8] - in[5 * 8];
|
||||
s6 = in[1 * 8] - in[6 * 8];
|
||||
s7 = in[0 * 8] - in[7 * 8];
|
||||
++in;
|
||||
}
|
||||
|
||||
// fdct4(step, step);
|
||||
x0 = s0 + s3;
|
||||
x1 = s1 + s2;
|
||||
x2 = s1 - s2;
|
||||
x3 = s0 - s3;
|
||||
t0 = (x0 + x1) * cospi_16_64;
|
||||
t1 = (x0 - x1) * cospi_16_64;
|
||||
t2 = x2 * cospi_24_64 + x3 * cospi_8_64;
|
||||
t3 = -x2 * cospi_8_64 + x3 * cospi_24_64;
|
||||
output[0] = (tran_low_t)fdct_round_shift(t0);
|
||||
output[2] = (tran_low_t)fdct_round_shift(t2);
|
||||
output[4] = (tran_low_t)fdct_round_shift(t1);
|
||||
output[6] = (tran_low_t)fdct_round_shift(t3);
|
||||
|
||||
// Stage 2
|
||||
t0 = (s6 - s5) * cospi_16_64;
|
||||
t1 = (s6 + s5) * cospi_16_64;
|
||||
t2 = fdct_round_shift(t0);
|
||||
t3 = fdct_round_shift(t1);
|
||||
|
||||
// Stage 3
|
||||
x0 = s4 + t2;
|
||||
x1 = s4 - t2;
|
||||
x2 = s7 - t3;
|
||||
x3 = s7 + t3;
|
||||
|
||||
// Stage 4
|
||||
t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
|
||||
t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
|
||||
t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
|
||||
t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
|
||||
output[1] = (tran_low_t)fdct_round_shift(t0);
|
||||
output[3] = (tran_low_t)fdct_round_shift(t2);
|
||||
output[5] = (tran_low_t)fdct_round_shift(t1);
|
||||
output[7] = (tran_low_t)fdct_round_shift(t3);
|
||||
output += 8;
|
||||
}
|
||||
in = intermediate;
|
||||
output = final_output;
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 8; ++i) {
|
||||
for (j = 0; j < 8; ++j)
|
||||
final_output[j + i * 8] /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
// The 2D transform is done with two passes which are actually pretty
|
||||
// similar. In the first one, we transform the columns and transpose
|
||||
// the results. In the second one, we transform the rows. To achieve that,
|
||||
// as the first pass results are transposed, we transpose the columns (that
|
||||
// is the transposed rows) and transpose the results (so that it goes back
|
||||
// in normal/row positions).
|
||||
int pass;
|
||||
// We need an intermediate buffer between passes.
|
||||
tran_low_t intermediate[256];
|
||||
const int16_t *in_pass0 = input;
|
||||
const tran_low_t *in = NULL;
|
||||
tran_low_t *out = intermediate;
|
||||
// Do the two transform/transpose passes
|
||||
for (pass = 0; pass < 2; ++pass) {
|
||||
tran_high_t step1[8]; // canbe16
|
||||
tran_high_t step2[8]; // canbe16
|
||||
tran_high_t step3[8]; // canbe16
|
||||
tran_high_t input[8]; // canbe16
|
||||
tran_high_t temp1, temp2; // needs32
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (0 == pass) {
|
||||
// Calculate input for the first 8 results.
|
||||
input[0] = (in_pass0[0 * stride] + in_pass0[15 * stride]) * 4;
|
||||
input[1] = (in_pass0[1 * stride] + in_pass0[14 * stride]) * 4;
|
||||
input[2] = (in_pass0[2 * stride] + in_pass0[13 * stride]) * 4;
|
||||
input[3] = (in_pass0[3 * stride] + in_pass0[12 * stride]) * 4;
|
||||
input[4] = (in_pass0[4 * stride] + in_pass0[11 * stride]) * 4;
|
||||
input[5] = (in_pass0[5 * stride] + in_pass0[10 * stride]) * 4;
|
||||
input[6] = (in_pass0[6 * stride] + in_pass0[ 9 * stride]) * 4;
|
||||
input[7] = (in_pass0[7 * stride] + in_pass0[ 8 * stride]) * 4;
|
||||
// Calculate input for the next 8 results.
|
||||
step1[0] = (in_pass0[7 * stride] - in_pass0[ 8 * stride]) * 4;
|
||||
step1[1] = (in_pass0[6 * stride] - in_pass0[ 9 * stride]) * 4;
|
||||
step1[2] = (in_pass0[5 * stride] - in_pass0[10 * stride]) * 4;
|
||||
step1[3] = (in_pass0[4 * stride] - in_pass0[11 * stride]) * 4;
|
||||
step1[4] = (in_pass0[3 * stride] - in_pass0[12 * stride]) * 4;
|
||||
step1[5] = (in_pass0[2 * stride] - in_pass0[13 * stride]) * 4;
|
||||
step1[6] = (in_pass0[1 * stride] - in_pass0[14 * stride]) * 4;
|
||||
step1[7] = (in_pass0[0 * stride] - in_pass0[15 * stride]) * 4;
|
||||
} else {
|
||||
// Calculate input for the first 8 results.
|
||||
input[0] = ((in[0 * 16] + 1) >> 2) + ((in[15 * 16] + 1) >> 2);
|
||||
input[1] = ((in[1 * 16] + 1) >> 2) + ((in[14 * 16] + 1) >> 2);
|
||||
input[2] = ((in[2 * 16] + 1) >> 2) + ((in[13 * 16] + 1) >> 2);
|
||||
input[3] = ((in[3 * 16] + 1) >> 2) + ((in[12 * 16] + 1) >> 2);
|
||||
input[4] = ((in[4 * 16] + 1) >> 2) + ((in[11 * 16] + 1) >> 2);
|
||||
input[5] = ((in[5 * 16] + 1) >> 2) + ((in[10 * 16] + 1) >> 2);
|
||||
input[6] = ((in[6 * 16] + 1) >> 2) + ((in[ 9 * 16] + 1) >> 2);
|
||||
input[7] = ((in[7 * 16] + 1) >> 2) + ((in[ 8 * 16] + 1) >> 2);
|
||||
// Calculate input for the next 8 results.
|
||||
step1[0] = ((in[7 * 16] + 1) >> 2) - ((in[ 8 * 16] + 1) >> 2);
|
||||
step1[1] = ((in[6 * 16] + 1) >> 2) - ((in[ 9 * 16] + 1) >> 2);
|
||||
step1[2] = ((in[5 * 16] + 1) >> 2) - ((in[10 * 16] + 1) >> 2);
|
||||
step1[3] = ((in[4 * 16] + 1) >> 2) - ((in[11 * 16] + 1) >> 2);
|
||||
step1[4] = ((in[3 * 16] + 1) >> 2) - ((in[12 * 16] + 1) >> 2);
|
||||
step1[5] = ((in[2 * 16] + 1) >> 2) - ((in[13 * 16] + 1) >> 2);
|
||||
step1[6] = ((in[1 * 16] + 1) >> 2) - ((in[14 * 16] + 1) >> 2);
|
||||
step1[7] = ((in[0 * 16] + 1) >> 2) - ((in[15 * 16] + 1) >> 2);
|
||||
}
|
||||
// Work on the first eight values; fdct8(input, even_results);
|
||||
{
|
||||
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
|
||||
tran_high_t t0, t1, t2, t3; // needs32
|
||||
tran_high_t x0, x1, x2, x3; // canbe16
|
||||
|
||||
// stage 1
|
||||
s0 = input[0] + input[7];
|
||||
s1 = input[1] + input[6];
|
||||
s2 = input[2] + input[5];
|
||||
s3 = input[3] + input[4];
|
||||
s4 = input[3] - input[4];
|
||||
s5 = input[2] - input[5];
|
||||
s6 = input[1] - input[6];
|
||||
s7 = input[0] - input[7];
|
||||
|
||||
// fdct4(step, step);
|
||||
x0 = s0 + s3;
|
||||
x1 = s1 + s2;
|
||||
x2 = s1 - s2;
|
||||
x3 = s0 - s3;
|
||||
t0 = (x0 + x1) * cospi_16_64;
|
||||
t1 = (x0 - x1) * cospi_16_64;
|
||||
t2 = x3 * cospi_8_64 + x2 * cospi_24_64;
|
||||
t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
|
||||
out[0] = (tran_low_t)fdct_round_shift(t0);
|
||||
out[4] = (tran_low_t)fdct_round_shift(t2);
|
||||
out[8] = (tran_low_t)fdct_round_shift(t1);
|
||||
out[12] = (tran_low_t)fdct_round_shift(t3);
|
||||
|
||||
// Stage 2
|
||||
t0 = (s6 - s5) * cospi_16_64;
|
||||
t1 = (s6 + s5) * cospi_16_64;
|
||||
t2 = fdct_round_shift(t0);
|
||||
t3 = fdct_round_shift(t1);
|
||||
|
||||
// Stage 3
|
||||
x0 = s4 + t2;
|
||||
x1 = s4 - t2;
|
||||
x2 = s7 - t3;
|
||||
x3 = s7 + t3;
|
||||
|
||||
// Stage 4
|
||||
t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
|
||||
t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
|
||||
t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
|
||||
t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
|
||||
out[2] = (tran_low_t)fdct_round_shift(t0);
|
||||
out[6] = (tran_low_t)fdct_round_shift(t2);
|
||||
out[10] = (tran_low_t)fdct_round_shift(t1);
|
||||
out[14] = (tran_low_t)fdct_round_shift(t3);
|
||||
}
|
||||
// Work on the next eight values; step1 -> odd_results
|
||||
{
|
||||
// step 2
|
||||
temp1 = (step1[5] - step1[2]) * cospi_16_64;
|
||||
temp2 = (step1[4] - step1[3]) * cospi_16_64;
|
||||
step2[2] = fdct_round_shift(temp1);
|
||||
step2[3] = fdct_round_shift(temp2);
|
||||
temp1 = (step1[4] + step1[3]) * cospi_16_64;
|
||||
temp2 = (step1[5] + step1[2]) * cospi_16_64;
|
||||
step2[4] = fdct_round_shift(temp1);
|
||||
step2[5] = fdct_round_shift(temp2);
|
||||
// step 3
|
||||
step3[0] = step1[0] + step2[3];
|
||||
step3[1] = step1[1] + step2[2];
|
||||
step3[2] = step1[1] - step2[2];
|
||||
step3[3] = step1[0] - step2[3];
|
||||
step3[4] = step1[7] - step2[4];
|
||||
step3[5] = step1[6] - step2[5];
|
||||
step3[6] = step1[6] + step2[5];
|
||||
step3[7] = step1[7] + step2[4];
|
||||
// step 4
|
||||
temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64;
|
||||
temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64;
|
||||
step2[1] = fdct_round_shift(temp1);
|
||||
step2[2] = fdct_round_shift(temp2);
|
||||
temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64;
|
||||
temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64;
|
||||
step2[5] = fdct_round_shift(temp1);
|
||||
step2[6] = fdct_round_shift(temp2);
|
||||
// step 5
|
||||
step1[0] = step3[0] + step2[1];
|
||||
step1[1] = step3[0] - step2[1];
|
||||
step1[2] = step3[3] + step2[2];
|
||||
step1[3] = step3[3] - step2[2];
|
||||
step1[4] = step3[4] - step2[5];
|
||||
step1[5] = step3[4] + step2[5];
|
||||
step1[6] = step3[7] - step2[6];
|
||||
step1[7] = step3[7] + step2[6];
|
||||
// step 6
|
||||
temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64;
|
||||
temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
|
||||
out[1] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[9] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
|
||||
temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64;
|
||||
out[5] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[13] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64;
|
||||
temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
|
||||
out[3] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[11] = (tran_low_t)fdct_round_shift(temp2);
|
||||
temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
|
||||
temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64;
|
||||
out[7] = (tran_low_t)fdct_round_shift(temp1);
|
||||
out[15] = (tran_low_t)fdct_round_shift(temp2);
|
||||
}
|
||||
// Do next column (which is a transposed row in second/horizontal pass)
|
||||
in++;
|
||||
in_pass0++;
|
||||
out += 16;
|
||||
}
|
||||
// Setup in/out for next pass.
|
||||
in = intermediate;
|
||||
out = output;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void vp9_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
vp9_fdct4x4_c(input, output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fdct8x8_c(const int16_t *input, tran_low_t *final_output,
|
||||
int stride) {
|
||||
vp9_fdct8x8_c(input, final_output, stride);
|
||||
}
|
||||
|
||||
void vp9_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
vp9_fdct16x16_c(input, output, stride);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
19
vpx_dsp/fwd_txfm.h
Normal file
19
vpx_dsp/fwd_txfm.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "vp9/common/vp9_idct.h"
|
||||
|
||||
static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
|
||||
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
|
||||
// TODO(debargha, peter.derivaz): Find new bounds for this assert
|
||||
// and make the bounds consts.
|
||||
// assert(INT16_MIN <= rv && rv <= INT16_MAX);
|
||||
return rv;
|
||||
}
|
@ -61,6 +61,19 @@ ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_loopfilter_sse2.c
|
||||
endif # CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
# forward transform
|
||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||
DSP_SRCS-yes += fwd_txfm.c
|
||||
DSP_SRCS-yes += fwd_txfm.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_impl_sse2.h
|
||||
ifeq ($(CONFIG_USE_X86INC),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/fwd_txfm_ssse3.asm
|
||||
endif
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/fwd_txfm_neon.c
|
||||
endif # CONFIG_VP9_ENCODER
|
||||
|
||||
# quantization
|
||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||
DSP_SRCS-yes += quantize.c
|
||||
DSP_SRCS-yes += quantize.h
|
||||
|
@ -123,6 +123,44 @@ if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
#
|
||||
# Encoder functions.
|
||||
#
|
||||
|
||||
#
|
||||
# Forward transform
|
||||
#
|
||||
if (vpx_config("CONFIG_VP9_ENCODER") eq "yes") {
|
||||
if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
add_proto qw/void vp9_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct4x4 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct8x8 sse2/;
|
||||
|
||||
add_proto qw/void vp9_highbd_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_highbd_fdct16x16 sse2/;
|
||||
} else {
|
||||
add_proto qw/void vp9_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct4x4 sse2/;
|
||||
|
||||
add_proto qw/void vp9_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct8x8 sse2 neon/, "$ssse3_x86_64_x86inc";
|
||||
|
||||
add_proto qw/void vp9_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
|
||||
specialize qw/vp9_fdct16x16 sse2/;
|
||||
} # CONFIG_VP9_HIGHBITDEPTH
|
||||
} # CONFIG_VP9_ENCODER
|
||||
|
||||
#
|
||||
# Quantization
|
||||
#
|
||||
if (vpx_config("CONFIG_VP9_ENCODER") eq "yes") {
|
||||
if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
|
||||
add_proto qw/void vp9_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
|
||||
|
@ -10,12 +10,15 @@
|
||||
|
||||
#include <emmintrin.h> // SSE2
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vp9/common/vp9_idct.h" // for cospi constants
|
||||
#include "vp9/encoder/vp9_dct.h"
|
||||
#include "vp9/encoder/x86/vp9_dct_sse2.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
// TODO(jingning) The high bit-depth functions need rework for performance.
|
||||
// After we properly fix the high bit-depth function implementations, this
|
||||
// file's dependency should be substantially simplified.
|
||||
#if DCT_HIGH_BIT_DEPTH
|
||||
#define ADD_EPI16 _mm_adds_epi16
|
||||
#define SUB_EPI16 _mm_subs_epi16
|
34
vpx_dsp/x86/fwd_txfm_sse2.c
Normal file
34
vpx_dsp/x86/fwd_txfm_sse2.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "./vpx_config.h"
|
||||
|
||||
#define DCT_HIGH_BIT_DEPTH 0
|
||||
|
||||
#define FDCT4x4_2D vp9_fdct4x4_sse2
|
||||
#define FDCT8x8_2D vp9_fdct8x8_sse2
|
||||
#define FDCT16x16_2D vp9_fdct16x16_sse2
|
||||
#include "vpx_dsp/x86/fwd_txfm_impl_sse2.h"
|
||||
#undef FDCT4x4_2D
|
||||
#undef FDCT8x8_2D
|
||||
#undef FDCT16x16_2D
|
||||
#undef DCT_HIGH_BIT_DEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
#define DCT_HIGH_BIT_DEPTH 1
|
||||
#define FDCT4x4_2D vp9_highbd_fdct4x4_sse2
|
||||
#define FDCT8x8_2D vp9_highbd_fdct8x8_sse2
|
||||
#define FDCT16x16_2D vp9_highbd_fdct16x16_sse2
|
||||
#include "vpx_dsp/x86/fwd_txfm_impl_sse2.h" // NOLINT
|
||||
#undef FDCT4x4_2D
|
||||
#undef FDCT8x8_2D
|
||||
#undef FDCT16x16_2D
|
||||
#undef DCT_HIGH_BIT_DEPTH
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
182
vpx_dsp/x86/fwd_txfm_ssse3.asm
Normal file
182
vpx_dsp/x86/fwd_txfm_ssse3.asm
Normal file
@ -0,0 +1,182 @@
|
||||
;
|
||||
; Copyright (c) 2015 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.
|
||||
;
|
||||
%include "third_party/x86inc/x86inc.asm"
|
||||
|
||||
; This file provides SSSE3 version of the forward transformation. Part
|
||||
; of the macro definitions are originally derived from the ffmpeg project.
|
||||
; The current version applies to x86 64-bit only.
|
||||
|
||||
SECTION_RODATA
|
||||
|
||||
pw_11585x2: times 8 dw 23170
|
||||
pd_8192: times 4 dd 8192
|
||||
|
||||
%macro TRANSFORM_COEFFS 2
|
||||
pw_%1_%2: dw %1, %2, %1, %2, %1, %2, %1, %2
|
||||
pw_%2_m%1: dw %2, -%1, %2, -%1, %2, -%1, %2, -%1
|
||||
%endmacro
|
||||
|
||||
TRANSFORM_COEFFS 11585, 11585
|
||||
TRANSFORM_COEFFS 15137, 6270
|
||||
TRANSFORM_COEFFS 16069, 3196
|
||||
TRANSFORM_COEFFS 9102, 13623
|
||||
|
||||
SECTION .text
|
||||
|
||||
%if ARCH_X86_64
|
||||
%macro SUM_SUB 3
|
||||
psubw m%3, m%1, m%2
|
||||
paddw m%1, m%2
|
||||
SWAP %2, %3
|
||||
%endmacro
|
||||
|
||||
; butterfly operation
|
||||
%macro MUL_ADD_2X 6 ; dst1, dst2, src, round, coefs1, coefs2
|
||||
pmaddwd m%1, m%3, %5
|
||||
pmaddwd m%2, m%3, %6
|
||||
paddd m%1, %4
|
||||
paddd m%2, %4
|
||||
psrad m%1, 14
|
||||
psrad m%2, 14
|
||||
%endmacro
|
||||
|
||||
%macro BUTTERFLY_4X 7 ; dst1, dst2, coef1, coef2, round, tmp1, tmp2
|
||||
punpckhwd m%6, m%2, m%1
|
||||
MUL_ADD_2X %7, %6, %6, %5, [pw_%4_%3], [pw_%3_m%4]
|
||||
punpcklwd m%2, m%1
|
||||
MUL_ADD_2X %1, %2, %2, %5, [pw_%4_%3], [pw_%3_m%4]
|
||||
packssdw m%1, m%7
|
||||
packssdw m%2, m%6
|
||||
%endmacro
|
||||
|
||||
; matrix transpose
|
||||
%macro INTERLEAVE_2X 4
|
||||
punpckh%1 m%4, m%2, m%3
|
||||
punpckl%1 m%2, m%3
|
||||
SWAP %3, %4
|
||||
%endmacro
|
||||
|
||||
%macro TRANSPOSE8X8 9
|
||||
INTERLEAVE_2X wd, %1, %2, %9
|
||||
INTERLEAVE_2X wd, %3, %4, %9
|
||||
INTERLEAVE_2X wd, %5, %6, %9
|
||||
INTERLEAVE_2X wd, %7, %8, %9
|
||||
|
||||
INTERLEAVE_2X dq, %1, %3, %9
|
||||
INTERLEAVE_2X dq, %2, %4, %9
|
||||
INTERLEAVE_2X dq, %5, %7, %9
|
||||
INTERLEAVE_2X dq, %6, %8, %9
|
||||
|
||||
INTERLEAVE_2X qdq, %1, %5, %9
|
||||
INTERLEAVE_2X qdq, %3, %7, %9
|
||||
INTERLEAVE_2X qdq, %2, %6, %9
|
||||
INTERLEAVE_2X qdq, %4, %8, %9
|
||||
|
||||
SWAP %2, %5
|
||||
SWAP %4, %7
|
||||
%endmacro
|
||||
|
||||
; 1D forward 8x8 DCT transform
|
||||
%macro FDCT8_1D 1
|
||||
SUM_SUB 0, 7, 9
|
||||
SUM_SUB 1, 6, 9
|
||||
SUM_SUB 2, 5, 9
|
||||
SUM_SUB 3, 4, 9
|
||||
|
||||
SUM_SUB 0, 3, 9
|
||||
SUM_SUB 1, 2, 9
|
||||
SUM_SUB 6, 5, 9
|
||||
%if %1 == 0
|
||||
SUM_SUB 0, 1, 9
|
||||
%endif
|
||||
|
||||
BUTTERFLY_4X 2, 3, 6270, 15137, m8, 9, 10
|
||||
|
||||
pmulhrsw m6, m12
|
||||
pmulhrsw m5, m12
|
||||
%if %1 == 0
|
||||
pmulhrsw m0, m12
|
||||
pmulhrsw m1, m12
|
||||
%else
|
||||
BUTTERFLY_4X 1, 0, 11585, 11585, m8, 9, 10
|
||||
SWAP 0, 1
|
||||
%endif
|
||||
|
||||
SUM_SUB 4, 5, 9
|
||||
SUM_SUB 7, 6, 9
|
||||
BUTTERFLY_4X 4, 7, 3196, 16069, m8, 9, 10
|
||||
BUTTERFLY_4X 5, 6, 13623, 9102, m8, 9, 10
|
||||
SWAP 1, 4
|
||||
SWAP 3, 6
|
||||
%endmacro
|
||||
|
||||
%macro DIVIDE_ROUND_2X 4 ; dst1, dst2, tmp1, tmp2
|
||||
psraw m%3, m%1, 15
|
||||
psraw m%4, m%2, 15
|
||||
psubw m%1, m%3
|
||||
psubw m%2, m%4
|
||||
psraw m%1, 1
|
||||
psraw m%2, 1
|
||||
%endmacro
|
||||
|
||||
INIT_XMM ssse3
|
||||
cglobal fdct8x8, 3, 5, 13, input, output, stride
|
||||
|
||||
mova m8, [pd_8192]
|
||||
mova m12, [pw_11585x2]
|
||||
pxor m11, m11
|
||||
|
||||
lea r3, [2 * strideq]
|
||||
lea r4, [4 * strideq]
|
||||
mova m0, [inputq]
|
||||
mova m1, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m2, [inputq]
|
||||
mova m3, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m4, [inputq]
|
||||
mova m5, [inputq + r3]
|
||||
lea inputq, [inputq + r4]
|
||||
mova m6, [inputq]
|
||||
mova m7, [inputq + r3]
|
||||
|
||||
; left shift by 2 to increase forward transformation precision
|
||||
psllw m0, 2
|
||||
psllw m1, 2
|
||||
psllw m2, 2
|
||||
psllw m3, 2
|
||||
psllw m4, 2
|
||||
psllw m5, 2
|
||||
psllw m6, 2
|
||||
psllw m7, 2
|
||||
|
||||
; column transform
|
||||
FDCT8_1D 0
|
||||
TRANSPOSE8X8 0, 1, 2, 3, 4, 5, 6, 7, 9
|
||||
|
||||
FDCT8_1D 1
|
||||
TRANSPOSE8X8 0, 1, 2, 3, 4, 5, 6, 7, 9
|
||||
|
||||
DIVIDE_ROUND_2X 0, 1, 9, 10
|
||||
DIVIDE_ROUND_2X 2, 3, 9, 10
|
||||
DIVIDE_ROUND_2X 4, 5, 9, 10
|
||||
DIVIDE_ROUND_2X 6, 7, 9, 10
|
||||
|
||||
mova [outputq + 0], m0
|
||||
mova [outputq + 16], m1
|
||||
mova [outputq + 32], m2
|
||||
mova [outputq + 48], m3
|
||||
mova [outputq + 64], m4
|
||||
mova [outputq + 80], m5
|
||||
mova [outputq + 96], m6
|
||||
mova [outputq + 112], m7
|
||||
|
||||
RET
|
||||
%endif
|
Loading…
x
Reference in New Issue
Block a user