Commit ad8290b8 authored by Lester Lu's avatar Lester Lu

New experiment: LGT

In previous ADSTs, DST-7 and DST-4 are used for length 4 and length
8/16/32, respectively. In this LGT experiment we explore transforms
between DST-4 and DST-7. When CONFIG_LGT flag is on, adst4 and adst8
are replaced by lgt4 and lgt8, the intermediate transforms with
pre-chosen parameters.

The LGTs applied here are lgt4_160 and lgt8_170, where the numbers
mean the self-loop weights times 100. The associated values for DST-7
and DST-4 are 100 and 200.

ovr_psnr:
lowres: -0.140
midres: -0.131
hdres: -0.078

These changes are not applied to the highbd scenario in the
current version.

Change-Id: I20600456da8766528b2b6b11aa28801e70af498e
parent 75b01004
......@@ -247,7 +247,33 @@ void aom_idct8x8_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) {
}
}
#if CONFIG_LGT
void aom_ilgt4_c(const tran_low_t *input, tran_low_t *output) {
if (!(input[0] | input[1] | input[2] | input[3])) {
output[0] = output[1] = output[2] = output[3] = 0;
return;
}
tran_high_t s[4] = { 0 };
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j) s[j] += lgtbasis4[i][j] * input[i];
for (int i = 0; i < 4; ++i) output[i] = WRAPLOW(dct_const_round_shift(s[i]));
}
void aom_ilgt8_c(const tran_low_t *input, tran_low_t *output) {
tran_high_t s[8] = { 0 };
for (int i = 0; i < 8; ++i)
for (int j = 0; j < 8; ++j) s[j] += lgtbasis8[i][j] * input[i];
for (int i = 0; i < 8; ++i) output[i] = WRAPLOW(dct_const_round_shift(s[i]));
}
#endif // CONFIG_LGT
void aom_iadst4_c(const tran_low_t *input, tran_low_t *output) {
#if CONFIG_LGT
aom_ilgt4_c(input, output);
#else
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;
tran_low_t x0 = input[0];
......@@ -282,9 +308,13 @@ void aom_iadst4_c(const tran_low_t *input, tran_low_t *output) {
output[1] = WRAPLOW(dct_const_round_shift(s1 + s3));
output[2] = WRAPLOW(dct_const_round_shift(s2));
output[3] = WRAPLOW(dct_const_round_shift(s0 + s1 - s3));
#endif // CONFIG_LGT
}
void aom_iadst8_c(const tran_low_t *input, tran_low_t *output) {
#if CONFIG_LGT
aom_ilgt8_c(input, output);
#else
int s0, s1, s2, s3, s4, s5, s6, s7;
tran_high_t x0 = input[7];
......@@ -359,6 +389,7 @@ void aom_iadst8_c(const tran_low_t *input, tran_low_t *output) {
output[5] = WRAPLOW(-x7);
output[6] = WRAPLOW(x5);
output[7] = WRAPLOW(-x1);
#endif // CONFIG_LGT
}
void aom_idct8x8_12_add_c(const tran_low_t *input, uint8_t *dest, int stride) {
......
......@@ -53,6 +53,11 @@ static INLINE tran_high_t check_range(tran_high_t input, int bd) {
#define WRAPLOW(x) ((int32_t)check_range(x, 8))
#define HIGHBD_WRAPLOW(x, bd) ((int32_t)check_range((x), bd))
#if CONFIG_LGT
void aom_ilgt4_c(const tran_low_t *input, tran_low_t *output);
void aom_ilgt8_c(const tran_low_t *input, tran_low_t *output);
#endif
void aom_idct4_c(const tran_low_t *input, tran_low_t *output);
void aom_idct8_c(const tran_low_t *input, tran_low_t *output);
void aom_idct16_c(const tran_low_t *input, tran_low_t *output);
......
......@@ -71,4 +71,32 @@ static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
return rv;
}
#if CONFIG_LGT
// LGT4--a modified ADST4
// LGT4 name: lgt4_160
// Self loops: 1.600, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000
static const tran_high_t lgtbasis4[4][4] = {
{ 3809, 9358, 13567, 15834 },
{ 10673, 15348, 2189, -13513 },
{ 15057, -157, -14961, 9290 },
{ 13481, -14619, 11144, -4151 },
};
// LGT8--a modified ADST8
// LGT8 name: lgt8_170
// Self loops: 1.700, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000
static const tran_high_t lgtbasis8[8][8] = {
{ 1858, 4947, 7850, 10458, 12672, 14411, 15607, 16217 },
{ 5494, 13022, 16256, 14129, 7343, -1864, -10456, -15601 },
{ 8887, 16266, 9500, -5529, -15749, -12273, 1876, 14394 },
{ 11870, 13351, -6199, -15984, -590, 15733, 7273, -12644 },
{ 14248, 5137, -15991, 291, 15893, -5685, -13963, 10425 },
{ 15716, -5450, -10010, 15929, -6665, -8952, 16036, -7835 },
{ 15533, -13869, 6559, 3421, -12009, 15707, -13011, 5018 },
{ 11357, -13726, 14841, -14600, 13025, -10259, 6556, -2254 },
};
#endif // CONFIG_LGT
#endif // AOM_DSP_TXFM_COMMON_H_
......@@ -1197,13 +1197,28 @@ static void inv_txfm_add_4x4(const tran_low_t *input, uint8_t *dest, int stride,
case DCT_DCT: av1_idct4x4_add(input, dest, stride, eob); break;
case ADST_DCT:
case DCT_ADST:
case ADST_ADST: av1_iht4x4_16_add(input, dest, stride, tx_type); break;
case ADST_ADST:
#if CONFIG_LGT
// LGT only exists in C verson
av1_iht4x4_16_add_c(input, dest, stride, tx_type);
break;
#else
av1_iht4x4_16_add(input, dest, stride, tx_type);
break;
#endif
#if CONFIG_EXT_TX
case FLIPADST_DCT:
case DCT_FLIPADST:
case FLIPADST_FLIPADST:
case ADST_FLIPADST:
case FLIPADST_ADST: av1_iht4x4_16_add(input, dest, stride, tx_type); break;
case FLIPADST_ADST:
#if CONFIG_LGT
av1_iht4x4_16_add_c(input, dest, stride, tx_type);
break;
#else
av1_iht4x4_16_add(input, dest, stride, tx_type);
break;
#endif
case V_DCT:
case H_DCT:
case V_ADST:
......@@ -1222,13 +1237,21 @@ static void inv_txfm_add_4x4(const tran_low_t *input, uint8_t *dest, int stride,
static void inv_txfm_add_4x8(const tran_low_t *input, uint8_t *dest, int stride,
int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht4x8_32_add_c(input, dest, stride, tx_type);
#else
av1_iht4x8_32_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_8x4(const tran_low_t *input, uint8_t *dest, int stride,
int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht8x4_32_add_c(input, dest, stride, tx_type);
#else
av1_iht8x4_32_add(input, dest, stride, tx_type);
#endif
}
// These will be used by the masked-tx experiment in the future.
......@@ -1236,38 +1259,62 @@ static void inv_txfm_add_8x4(const tran_low_t *input, uint8_t *dest, int stride,
static void inv_txfm_add_4x16(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht4x16_64_add_c(input, dest, stride, tx_type);
#else
av1_iht4x16_64_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_16x4(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht16x4_64_add_c(input, dest, stride, tx_type);
#else
av1_iht16x4_64_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_8x32(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht8x32_256_add_c(input, dest, stride, tx_type);
#else
av1_iht8x32_256_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_32x8(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht32x8_256_add_c(input, dest, stride, tx_type);
#else
av1_iht32x8_256_add(input, dest, stride, tx_type);
#endif
}
#endif
static void inv_txfm_add_8x16(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht8x16_128_add_c(input, dest, stride, tx_type);
#else
av1_iht8x16_128_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_16x8(const tran_low_t *input, uint8_t *dest,
int stride, int eob, TX_TYPE tx_type) {
(void)eob;
#if CONFIG_LGT
av1_iht16x8_128_add_c(input, dest, stride, tx_type);
#else
av1_iht16x8_128_add(input, dest, stride, tx_type);
#endif
}
static void inv_txfm_add_16x32(const tran_low_t *input, uint8_t *dest,
......@@ -1289,13 +1336,27 @@ static void inv_txfm_add_8x8(const tran_low_t *input, uint8_t *dest, int stride,
case DCT_DCT: idct8x8_add(input, dest, stride, param); break;
case ADST_DCT:
case DCT_ADST:
case ADST_ADST: av1_iht8x8_64_add(input, dest, stride, tx_type); break;
case ADST_ADST:
#if CONFIG_LGT
av1_iht8x8_64_add_c(input, dest, stride, tx_type);
break;
#else
av1_iht8x8_64_add(input, dest, stride, tx_type);
break;
#endif
#if CONFIG_EXT_TX
case FLIPADST_DCT:
case DCT_FLIPADST:
case FLIPADST_FLIPADST:
case ADST_FLIPADST:
case FLIPADST_ADST: av1_iht8x8_64_add(input, dest, stride, tx_type); break;
case FLIPADST_ADST:
#if CONFIG_LGT
av1_iht8x8_64_add_c(input, dest, stride, tx_type);
break;
#else
av1_iht8x8_64_add(input, dest, stride, tx_type);
break;
#endif
case V_DCT:
case H_DCT:
case V_ADST:
......
......@@ -727,7 +727,33 @@ static void fdct32(const tran_low_t *input, tran_low_t *output) {
#ifndef AV1_DCT_GTEST
#if CONFIG_LGT
static void flgt4(const tran_low_t *input, tran_low_t *output) {
if (!(input[0] | input[1] | input[2] | input[3])) {
output[0] = output[1] = output[2] = output[3] = 0;
return;
}
tran_high_t s[4] = { 0 };
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j) s[j] += lgtbasis4[j][i] * input[i];
for (int i = 0; i < 4; ++i) output[i] = (tran_low_t)fdct_round_shift(s[i]);
}
static void flgt8(const tran_low_t *input, tran_low_t *output) {
tran_high_t s[8] = { 0 };
for (int i = 0; i < 8; ++i)
for (int j = 0; j < 8; ++j) s[j] += lgtbasis8[j][i] * input[i];
for (int i = 0; i < 8; ++i) output[i] = (tran_low_t)fdct_round_shift(s[i]);
}
#endif // CONFIG_LGT
static void fadst4(const tran_low_t *input, tran_low_t *output) {
#if CONFIG_LGT
flgt4(input, output);
#else
tran_high_t x0, x1, x2, x3;
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;
......@@ -765,9 +791,13 @@ static void fadst4(const tran_low_t *input, tran_low_t *output) {
output[1] = (tran_low_t)fdct_round_shift(s1);
output[2] = (tran_low_t)fdct_round_shift(s2);
output[3] = (tran_low_t)fdct_round_shift(s3);
#endif // CONFIG_LGT
}
static void fadst8(const tran_low_t *input, tran_low_t *output) {
#if CONFIG_LGT
flgt8(input, output);
#else
tran_high_t s0, s1, s2, s3, s4, s5, s6, s7;
tran_high_t x0 = input[7];
......@@ -836,6 +866,7 @@ static void fadst8(const tran_low_t *input, tran_low_t *output) {
output[5] = (tran_low_t)-x7;
output[6] = (tran_low_t)x5;
output[7] = (tran_low_t)-x1;
#endif // CONFIG_LGT
}
static void fadst16(const tran_low_t *input, tran_low_t *output) {
......
......@@ -52,35 +52,56 @@ static void fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
return;
}
#if CONFIG_LGT
// only C version has LGTs
av1_fht4x4_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht4x4(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht4x8_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht4x8(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht8x4_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht8x4(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht8x16_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht8x16(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht16x8_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht16x8(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
......@@ -101,7 +122,11 @@ static void fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht8x8_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht8x8(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
......@@ -137,28 +162,44 @@ static void fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht16x4_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht16x4(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht4x16_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht4x16(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht32x8_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht32x8(src_diff, coeff, diff_stride, tx_type);
#endif
}
static void fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TX_TYPE tx_type,
FWD_TXFM_OPT fwd_txfm_opt) {
(void)fwd_txfm_opt;
#if CONFIG_LGT
av1_fht8x32_c(src_diff, coeff, diff_stride, tx_type);
#else
av1_fht8x32(src_diff, coeff, diff_stride, tx_type);
#endif
}
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
......
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