Skip to content

Commit

Permalink
New experiment: LGT
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Lester Lu committed Jun 26, 2017
1 parent 75b0100 commit ad8290b
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 4 deletions.
31 changes: 31 additions & 0 deletions aom_dsp/inv_txfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions aom_dsp/inv_txfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 28 additions & 0 deletions aom_dsp/txfm_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
69 changes: 65 additions & 4 deletions av1/common/idct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -1222,52 +1237,84 @@ 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.
#if CONFIG_RECT_TX && CONFIG_EXT_TX && CONFIG_RECT_TX_EXT
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,
Expand All @@ -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:
Expand Down
31 changes: 31 additions & 0 deletions av1/encoder/dct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit ad8290b

Please sign in to comment.