Introduce CONFIG_DDT_INTER experiment
This patch introduces an experiment under CONFIG_DDT_INTER flag, and
integrates it with CONFIG_IST.
Note that this is the same as CONFIG_MODE_DEP_INTER_TX in experimental
branch, but renamed as CONFIG_DDT_INTER because the transforms added
are not mode-dependent.
Change-Id: I5112c2b751e65a526c08adcc0823291d212fa20c
diff --git a/av1/common/av1_inv_txfm1d.c b/av1/common/av1_inv_txfm1d.c
index bd789a4..0e9c5a5 100644
--- a/av1/common/av1_inv_txfm1d.c
+++ b/av1/common/av1_inv_txfm1d.c
@@ -654,6 +654,47 @@
bf1[31] = clamp_value(bf0[0] - bf0[31], stage_range[stage]);
}
+#if CONFIG_DDT_INTER
+void av1_iklt4(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 4; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 4; j++) {
+ sum += input[j] * klt4_inter[j * 4 + i];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+
+void av1_iklt8(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 8; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 8; j++) {
+ sum += input[j] * klt8_inter[j * 8 + i];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+
+void av1_iklt16(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 16; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 16; j++) {
+ sum += input[j] * klt16_inter[j * 16 + i];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+#endif // CONFIG_DDT_INTER
+
void av1_iadst4(const int32_t *input, int32_t *output, int8_t cos_bit,
const int8_t *stage_range) {
int bit = cos_bit;
diff --git a/av1/common/av1_inv_txfm1d.h b/av1/common/av1_inv_txfm1d.h
index 84bbfaf..31c6e09 100644
--- a/av1/common/av1_inv_txfm1d.h
+++ b/av1/common/av1_inv_txfm1d.h
@@ -15,6 +15,10 @@
#include "av1/common/av1_txfm.h"
+#if CONFIG_DDT_INTER
+#include "av1/common/ddtx_bases.h"
+#endif // CONFIG_DDT_INTER
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -59,6 +63,14 @@
void av1_iidentity32_c(const int32_t *input, int32_t *output, int8_t cos_bit,
const int8_t *stage_range);
+#if CONFIG_DDT_INTER
+void av1_iklt4(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+void av1_iklt8(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+void av1_iklt16(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+#endif // CONFIG_DDT_INTER
#ifdef __cplusplus
}
#endif
diff --git a/av1/common/av1_inv_txfm2d.c b/av1/common/av1_inv_txfm2d.c
index ff80d55..56a479c 100644
--- a/av1/common/av1_inv_txfm2d.c
+++ b/av1/common/av1_inv_txfm2d.c
@@ -125,6 +125,11 @@
#if CONFIG_DST_32X32
case TXFM_TYPE_ADST32: return av1_iadst32;
#endif // CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ case TXFM_TYPE_DDT4: return av1_iklt4;
+ case TXFM_TYPE_DDT8: return av1_iklt8;
+ case TXFM_TYPE_DDT16: return av1_iklt16;
+#endif // CONFIG_DDT_INTER
case TXFM_TYPE_IDENTITY4: return av1_iidentity4_c;
case TXFM_TYPE_IDENTITY8: return av1_iidentity8_c;
case TXFM_TYPE_IDENTITY16: return av1_iidentity16_c;
diff --git a/av1/common/av1_txfm.c b/av1/common/av1_txfm.c
index 4c4a4c9..0fe1e7f 100644
--- a/av1/common/av1_txfm.c
+++ b/av1/common/av1_txfm.c
@@ -223,6 +223,25 @@
}
}
+#if CONFIG_DDT_INTER
+const TXFM_TYPE av1_txfm_type_ls[5][TX_TYPES_1D] = {
+ { TXFM_TYPE_DCT4, TXFM_TYPE_ADST4, TXFM_TYPE_ADST4, TXFM_TYPE_IDENTITY4,
+ TXFM_TYPE_DDT4 },
+ { TXFM_TYPE_DCT8, TXFM_TYPE_ADST8, TXFM_TYPE_ADST8, TXFM_TYPE_IDENTITY8,
+ TXFM_TYPE_DDT8 },
+ { TXFM_TYPE_DCT16, TXFM_TYPE_ADST16, TXFM_TYPE_ADST16, TXFM_TYPE_IDENTITY16,
+ TXFM_TYPE_DDT16 },
+#if CONFIG_DST_32X32
+ { TXFM_TYPE_DCT32, TXFM_TYPE_ADST32, TXFM_TYPE_ADST32, TXFM_TYPE_IDENTITY32,
+ TXFM_TYPE_ADST32 },
+#else
+ { TXFM_TYPE_DCT32, TXFM_TYPE_INVALID, TXFM_TYPE_INVALID, TXFM_TYPE_IDENTITY32,
+ TXFM_TYPE_INVALID },
+#endif
+ { TXFM_TYPE_DCT64, TXFM_TYPE_INVALID, TXFM_TYPE_INVALID, TXFM_TYPE_INVALID,
+ TXFM_TYPE_INVALID }
+};
+#else
const TXFM_TYPE av1_txfm_type_ls[5][TX_TYPES_1D] = {
{ TXFM_TYPE_DCT4, TXFM_TYPE_ADST4, TXFM_TYPE_ADST4, TXFM_TYPE_IDENTITY4 },
{ TXFM_TYPE_DCT8, TXFM_TYPE_ADST8, TXFM_TYPE_ADST8, TXFM_TYPE_IDENTITY8 },
@@ -235,6 +254,7 @@
#endif // CONFIG_DST_32X32
{ TXFM_TYPE_DCT64, TXFM_TYPE_INVALID, TXFM_TYPE_INVALID, TXFM_TYPE_INVALID }
};
+#endif // CONFIG_DDT_INTER
const int8_t av1_txfm_stage_num_list[TXFM_TYPES] = {
4, // TXFM_TYPE_DCT4
@@ -249,6 +269,11 @@
1, // TXFM_TYPE_IDENTITY8
1, // TXFM_TYPE_IDENTITY16
1, // TXFM_TYPE_IDENTITY32
+#if CONFIG_DDT_INTER
+ 1, // TXFM_TYPE_DDT4 (not used)
+ 1, // TXFM_TYPE_DDT8 (not used)
+ 1, // TXFM_TYPE_DDT16 (not used)
+#endif // CONFIG_DDT_INTER
#if CONFIG_DST_32X32
1, // TXFM_TYPE_ADST32
#endif
diff --git a/av1/common/av1_txfm.h b/av1/common/av1_txfm.h
index ae6d8cf..5958434 100644
--- a/av1/common/av1_txfm.h
+++ b/av1/common/av1_txfm.h
@@ -45,6 +45,10 @@
#define DST_32X32_PREC_BITS 7
#endif // CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+#define KLT_PREC_BITS 10
+#endif // CONFIG_DDT_INTER
+
#define MAX_TXFM_STAGE_NUM 12
static const int cos_bit_min = 10;
@@ -136,6 +140,11 @@
TXFM_TYPE_IDENTITY8,
TXFM_TYPE_IDENTITY16,
TXFM_TYPE_IDENTITY32,
+#if CONFIG_DDT_INTER
+ TXFM_TYPE_DDT4,
+ TXFM_TYPE_DDT8,
+ TXFM_TYPE_DDT16, // DST type 7
+#endif // CONFIG_DDT_INTER
#if CONFIG_DST_32X32
TXFM_TYPE_ADST32,
#endif
@@ -143,6 +152,24 @@
TXFM_TYPE_INVALID,
} UENUM1BYTE(TXFM_TYPE);
+#if CONFIG_DDT_INTER
+static INLINE int idx_flip(const int txw, const int txh, const int idxr,
+ const int idxc, const int ud_flip,
+ const int lr_flip) {
+ if (ud_flip == 1 && lr_flip == 1) {
+ // return (txh - idxr - 1) * txw + txw - idxc - 1;
+ return (txh - idxr) * txw - idxc - 1;
+ } else if (ud_flip == 1 && lr_flip == 0) {
+ return (txh - idxr - 1) * txw + idxc;
+ } else if (ud_flip == 0 && lr_flip == 1) {
+ // return idxr * txw + txw - idxc - 1;
+ return (idxr + 1) * txw - idxc - 1;
+ } else {
+ return idxr * txw + idxc;
+ }
+}
+#endif // CONFIG_DDT_INTER
+
typedef struct TXFM_2D_FLIP_CFG {
TX_SIZE tx_size;
int ud_flip; // flip upside down
@@ -172,22 +199,38 @@
case H_DCT:
case V_ADST:
case H_ADST:
+#if CONFIG_DDT_INTER
+ case DDT_DDT:
+ case DDT_DCT:
+ case DCT_DDT:
+#endif // CONFIG_DDT_INTER
*ud_flip = 0;
*lr_flip = 0;
break;
case FLIPADST_DCT:
case FLIPADST_ADST:
case V_FLIPADST:
+#if CONFIG_DDT_INTER
+ case FLIPDDT_DCT:
+ case FLIPDDT_DDT:
+#endif // CONFIG_DDT_INTER
*ud_flip = 1;
*lr_flip = 0;
break;
case DCT_FLIPADST:
case ADST_FLIPADST:
case H_FLIPADST:
+#if CONFIG_DDT_INTER
+ case DCT_FLIPDDT:
+ case DDT_FLIPDDT:
+#endif // CONFIG_DDT_INTER
*ud_flip = 0;
*lr_flip = 1;
break;
case FLIPADST_FLIPADST:
+#if CONFIG_DDT_INTER
+ case FLIPDDT_FLIPDDT:
+#endif // CONFIG_DDT_INTER
*ud_flip = 1;
*lr_flip = 1;
break;
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index ecab171..b5bf2a9 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -1271,6 +1271,35 @@
1, 2, 5, 7, 12, 16,
};
+#if CONFIG_DDT_INTER
+// Whether or not the primary transform is a ddtx
+static INLINE int has_ddtx(TX_TYPE tx_type) {
+ return tx_type >= DDT_DDT && tx_type <= DDT_FLIPDDT;
+}
+
+static INLINE TX_TYPE ddtx_to_trigtx(TX_TYPE tx_type) {
+ switch (tx_type) {
+ case DDT_DDT: return ADST_ADST;
+ case DDT_DCT: return ADST_DCT;
+ case DCT_DDT: return DCT_ADST;
+ case FLIPDDT_FLIPDDT: return FLIPADST_FLIPADST;
+ case FLIPDDT_DCT: return FLIPADST_DCT;
+ case DCT_FLIPDDT: return DCT_FLIPADST;
+ case FLIPDDT_DDT: return FLIPADST_ADST;
+ case DDT_FLIPDDT: return ADST_FLIPADST;
+ default: assert(0); return 0;
+ }
+}
+
+static const int av1_ext_tx_used[EXT_TX_SET_TYPES][TX_TYPES] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+};
+#else
static const int av1_ext_tx_used[EXT_TX_SET_TYPES][TX_TYPES] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
@@ -1279,6 +1308,7 @@
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};
+#endif // CONFIG_DDT_INTER
static const uint16_t av1_reduced_intra_tx_used_flag[INTRA_MODES] = {
0x080F, // DC_PRED: 0000 1000 0000 1111
@@ -1307,7 +1337,11 @@
static const TxSetType av1_ext_tx_set_lookup[2][2] = {
{ EXT_TX_SET_DTT4_IDTX_1DDCT, EXT_TX_SET_DTT4_IDTX },
+#if CONFIG_DDT_INTER
+ { EXT_TX_SET_ALL24, EXT_TX_SET_DTT9_IDTX_1DDCT },
+#else
{ EXT_TX_SET_ALL16, EXT_TX_SET_DTT9_IDTX_1DDCT },
+#endif // CONFIG_DDT_INTER
};
#if CONFIG_DST_32X32
@@ -1548,24 +1582,44 @@
*
*/
static INLINE void disable_secondary_tx_type(TX_TYPE *tx_type) {
+#if CONFIG_DDT_INTER
+ // Mask both secondary tx and ddtx flag
+ *tx_type &= (*tx_type & 0x40) ? 0x1f : 0x0f;
+#else
*tx_type &= 0x0f;
+#endif // CONFIG_DDT_INTER
}
/*
* This function masks primary transform type used by the transform block
*/
static INLINE void disable_primary_tx_type(TX_TYPE *tx_type) {
+#if CONFIG_DDT_INTER
+ *tx_type &= 0x30; // Set the 6th bit to zero and apply masking
+#else
*tx_type &= 0xf0;
+#endif
}
/*
- * This function returns primary transform type used by the transform block
+ * This function returns primary transform type used by the transform block.
+ * If data-driven transform is enabled (CONFIG_DDT_INTER), bit 6 of
+ * tx_type stores is_ddtx. If it is 1, then take 5 bits (ddtx can be from 16 to
+ * 23). Otherwise, take 4 bits (primary tx ranges from 0 to 16).
*/
static INLINE TX_TYPE get_primary_tx_type(TX_TYPE tx_type) {
+#if CONFIG_DDT_INTER
+ return (tx_type & 0x40) ? (tx_type & 0x1f) : (tx_type & 0x0f);
+#else
return tx_type & 0x0f;
+#endif // CONFIG_DDT_INTER
}
/*
* This function returns secondary transform type used by the transform block
*/
static INLINE TX_TYPE get_secondary_tx_type(TX_TYPE tx_type) {
+#if CONFIG_DDT_INTER
+ if (tx_type & 0x40) return 0;
+ tx_type &= 0x3f; // Set the 6th bit to zero
+#endif // CONFIG_DDT_INTER
return (tx_type >> 4);
}
/*
@@ -1647,6 +1701,12 @@
// Secondary transforms are disabled for chroma
disable_secondary_tx_type(&tx_type);
#endif // CONFIG_IST
+#if CONFIG_DDT_INTER
+ // In DDT_INTER, transform pruning is not applied to ddtx, which causes
+ // a mismatch if uv_tx_type has ddtx in it. In this case, we replace ddtx
+ // by adst as a workaround.
+ if (has_ddtx(tx_type)) tx_type = ddtx_to_trigtx(tx_type);
+#endif // CONFIG_DDT_INTER
} else {
// In intra mode, uv planes don't share the same prediction mode as y
// plane, so the tx_type should not be shared
diff --git a/av1/common/common_data.h b/av1/common/common_data.h
index abe5cbd..79be189 100644
--- a/av1/common/common_data.h
+++ b/av1/common/common_data.h
@@ -157,12 +157,20 @@
DCT_1D, ADST_1D, DCT_1D, ADST_1D,
FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
+#if CONFIG_DDT_INTER
+ DDT1_1D, DDT1_1D, DCT_1D, DDT1_1D, DDT1_1D, DCT_1D,
+ DDT1_1D, DDT1_1D,
+#endif // CONFIG_DDT_INTER
};
static const TX_TYPE_1D htx_tab[TX_TYPES] = {
DCT_1D, DCT_1D, ADST_1D, ADST_1D,
DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
+#if CONFIG_DDT_INTER
+ DDT1_1D, DCT_1D, DDT1_1D, DDT1_1D, DCT_1D, DDT1_1D,
+ DDT1_1D, DDT1_1D,
+#endif // CONFIG_DDT_INTER
};
#define TXSIZE_CAT_INVALID (-1)
diff --git a/av1/common/ddtx_bases.h b/av1/common/ddtx_bases.h
new file mode 100644
index 0000000..8423f05
--- /dev/null
+++ b/av1/common/ddtx_bases.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 3-Clause Clear License
+ * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
+ * License was not distributed with this source code in the LICENSE file, you
+ * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the
+ * Alliance for Open Media Patent License 1.0 was not distributed with this
+ * source code in the PATENTS file, you can obtain it at
+ * aomedia.org/license/patent-license/.
+ */
+
+#ifndef DDT_BASES_H_
+#define DDT_BASES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Inter KLTs
+// Quantized with 2^10 and scale factor 1.4142135623730951
+static const int32_t klt4_inter[16] = {
+ -25, 17, 668, 1284, -60, 370, 1238, -651,
+ 505, 1317, -293, 145, 1356, -474, 176, -59,
+};
+
+// Quantized with 2^10 and scale factor 2
+static const int32_t klt8_inter[64] = {
+ 33, 35, 28, 89, 402, 1017, 1404, 1009, 0, -34, -10,
+ 415, 1185, 1090, -330, -1148, 0, 1, 365, 1211, 968, -680,
+ -549, 947, -63, -466, -1272, -935, 652, 158, -719, 717, 911,
+ 1374, 590, -619, 89, 414, -639, 399, 1342, 295, -945, 276,
+ 338, -724, 709, -443, 1030, -859, -116, 707, -894, 807, -587,
+ 295, 705, -1124, 1091, -845, 587, -370, 204, -85,
+};
+
+// Quantized with 2^10 and scale factor 2.8284271247461903
+static const int32_t klt16_inter[256] = {
+ 325, 377, 419, 468, 526, 597, 684, 785, 860, 910, 951,
+ 968, 947, 878, 765, 607, 348, 430, 500, 576, 656, 731,
+ 794, 815, 713, 441, 32, -462, -912, -1174, -1159, -879, 627,
+ 744, 781, 778, 711, 557, 293, -87, -521, -926, -1138, -963,
+ -356, 433, 929, 888, 634, 743, 725, 625, 417, 84, -389,
+ -887, -1030, -581, 296, 1047, 999, 83, -866, -1031, 547, 605,
+ 487, 245, -88, -475, -829, -864, -237, 803, 1170, 204, -1103,
+ -1018, 352, 1127, 825, 836, 515, -13, -620, -1048, -878, 41,
+ 985, 797, -430, -942, 146, 969, 63, -921, 739, 660, 180,
+ -436, -919, -797, 167, 1068, 458, -946, -655, 853, 538, -950,
+ -441, 942, 945, 643, -293, -1091, -910, 308, 1161, 272, -957,
+ -265, 865, -49, -786, 474, 575, -741, 977, 297, -853, -1024,
+ 160, 1054, 135, -967, 73, 888, -522, -560, 884, -164, -831,
+ 776, 1055, -136, -1213, -270, 1092, 292, -1005, 64, 828, -660,
+ -217, 833, -586, -213, 861, -655, 951, -596, -952, 721, 666,
+ -934, -115, 933, -714, -208, 876, -794, 117, 592, -927, 573,
+ 858, -899, -368, 1040, -391, -668, 960, -363, -451, 914, -768,
+ 176, 496, -929, 966, -521, 672, -948, 171, 719, -927, 341,
+ 441, -903, 848, -399, -200, 720, -1025, 1055, -858, 412, 531,
+ -912, 601, 97, -681, 760, -391, -170, 673, -1016, 1145, -1099,
+ 942, -721, 478, -204, 549, -1012, 892, -345, -384, 947, -1202,
+ 1186, -1021, 792, -583, 397, -248, 139, -69, 20, 452, -1009,
+ 1334, -1426, 1286, -1010, 681, -398, 198, -73, -5, 48, -64,
+ 60, -49, 24,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DDT_BASES_H
diff --git a/av1/common/entropy.c b/av1/common/entropy.c
index 2553155..8bc639f 100644
--- a/av1/common/entropy.c
+++ b/av1/common/entropy.c
@@ -269,6 +269,19 @@
for (int i = 0; i < FRAME_LF_COUNT; i++) {
RESET_CDF_COUNTER(fc->delta_lf_multi_cdf[i], DELTA_LF_PROBS + 1);
}
+#if CONFIG_DDT_INTER
+ RESET_CDF_COUNTER(fc->use_ddtx_inter_cdf, 2);
+ RESET_CDF_COUNTER_STRIDE(fc->ddtx_type_inter_cdf, 8, CDF_SIZE(DDT_TYPES));
+ RESET_CDF_COUNTER_STRIDE(fc->intra_ext_tx_cdf[1], INTRA_TX_SET1,
+ CDF_SIZE(TX_TYPES_TRIG));
+ RESET_CDF_COUNTER_STRIDE(fc->intra_ext_tx_cdf[2], INTRA_TX_SET2,
+ CDF_SIZE(TX_TYPES_TRIG));
+ RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[1], 16,
+ CDF_SIZE(TX_TYPES_TRIG));
+ RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[2], 12,
+ CDF_SIZE(TX_TYPES_TRIG));
+ RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[3], 2, CDF_SIZE(TX_TYPES_TRIG));
+#else
RESET_CDF_COUNTER_STRIDE(fc->intra_ext_tx_cdf[1], INTRA_TX_SET1,
CDF_SIZE(TX_TYPES));
RESET_CDF_COUNTER_STRIDE(fc->intra_ext_tx_cdf[2], INTRA_TX_SET2,
@@ -276,6 +289,7 @@
RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[1], 16, CDF_SIZE(TX_TYPES));
RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[2], 12, CDF_SIZE(TX_TYPES));
RESET_CDF_COUNTER_STRIDE(fc->inter_ext_tx_cdf[3], 2, CDF_SIZE(TX_TYPES));
+#endif // CONFIG_DDT_INTER
RESET_CDF_COUNTER(fc->cfl_sign_cdf, CFL_JOINT_SIGNS);
RESET_CDF_COUNTER(fc->cfl_alpha_cdf, CFL_ALPHABET_SIZE);
#if CONFIG_IST
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 3c17d18..f99767b 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -300,8 +300,13 @@
}
};
+#if CONFIG_DDT_INTER
+static const aom_cdf_prob default_intra_ext_tx_cdf
+ [EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES][CDF_SIZE(TX_TYPES_TRIG)] = {
+#else
static const aom_cdf_prob default_intra_ext_tx_cdf
[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES][CDF_SIZE(TX_TYPES)] = {
+#endif // CONFIG_DDT_INTER
{
{
{ 0 },
@@ -617,9 +622,15 @@
#endif // CONFIG_FORWARDSKIP
};
+#if CONFIG_DDT_INTER
+static const aom_cdf_prob
+ default_inter_ext_tx_cdf[EXT_TX_SETS_INTER][EXT_TX_SIZES][CDF_SIZE(
+ TX_TYPES_TRIG)] = {
+#else
static const aom_cdf_prob
default_inter_ext_tx_cdf[EXT_TX_SETS_INTER][EXT_TX_SIZES][CDF_SIZE(
TX_TYPES)] = {
+#endif // CONFIG_DDT_INTER
{
{ 0 },
{ 0 },
@@ -654,6 +665,24 @@
},
};
+#if CONFIG_DDT_INTER
+static const aom_cdf_prob
+ default_ddtx_type_inter_cdf[EXT_TX_SIZES][CDF_SIZE(DDT_TYPES)] = {
+ { AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672) },
+ { AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672) },
+ { AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672) },
+ { AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672) },
+ };
+
+static const aom_cdf_prob default_use_ddtx_inter_cdf[EXT_TX_SIZES]
+ [CDF_SIZE(2)] = {
+ { AOM_CDF2(16384) },
+ { AOM_CDF2(16384) },
+ { AOM_CDF2(16384) },
+ { AOM_CDF2(16384) },
+ };
+#endif // CONFIG_DDT_INTER
+
static const aom_cdf_prob default_cfl_sign_cdf[CDF_SIZE(CFL_JOINT_SIGNS)] = {
AOM_CDF8(1418, 2123, 13340, 18405, 26972, 28343, 32294)
};
@@ -1876,6 +1905,10 @@
av1_copy(fc->partition_cdf, default_partition_cdf);
av1_copy(fc->intra_ext_tx_cdf, default_intra_ext_tx_cdf);
av1_copy(fc->inter_ext_tx_cdf, default_inter_ext_tx_cdf);
+#if CONFIG_DDT_INTER
+ av1_copy(fc->ddtx_type_inter_cdf, default_ddtx_type_inter_cdf);
+ av1_copy(fc->use_ddtx_inter_cdf, default_use_ddtx_inter_cdf);
+#endif // CONFIG_DDT_INTER
av1_copy(fc->skip_mode_cdfs, default_skip_mode_cdfs);
av1_copy(fc->skip_txfm_cdfs, default_skip_txfm_cdfs);
#if CONFIG_CONTEXT_DERIVATION
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 51a4768..2955367 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -254,10 +254,19 @@
aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)];
aom_cdf_prob delta_lf_multi_cdf[FRAME_LF_COUNT][CDF_SIZE(DELTA_LF_PROBS + 1)];
aom_cdf_prob delta_lf_cdf[CDF_SIZE(DELTA_LF_PROBS + 1)];
+#if CONFIG_DDT_INTER
+ aom_cdf_prob ddtx_type_inter_cdf[EXT_TX_SIZES][CDF_SIZE(DDT_TYPES)];
+ aom_cdf_prob use_ddtx_inter_cdf[EXT_TX_SIZES][CDF_SIZE(2)];
+ aom_cdf_prob intra_ext_tx_cdf[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
+ [CDF_SIZE(TX_TYPES_TRIG)];
+ aom_cdf_prob inter_ext_tx_cdf[EXT_TX_SETS_INTER][EXT_TX_SIZES]
+ [CDF_SIZE(TX_TYPES_TRIG)];
+#else
aom_cdf_prob intra_ext_tx_cdf[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
[CDF_SIZE(TX_TYPES)];
aom_cdf_prob inter_ext_tx_cdf[EXT_TX_SETS_INTER][EXT_TX_SIZES]
[CDF_SIZE(TX_TYPES)];
+#endif // CONFIG_DDT_INTER
aom_cdf_prob cfl_sign_cdf[CDF_SIZE(CFL_JOINT_SIGNS)];
aom_cdf_prob cfl_alpha_cdf[CFL_ALPHA_CONTEXTS][CDF_SIZE(CFL_ALPHABET_SIZE)];
#if CONFIG_IST
@@ -286,7 +295,11 @@
};
#endif // CONFIG_FORWARDSKIP
+#if CONFIG_DDT_INTER
+static const int av1_ext_tx_ind[EXT_TX_SET_TYPES][TX_TYPES_TRIG] = {
+#else
static const int av1_ext_tx_ind[EXT_TX_SET_TYPES][TX_TYPES] = {
+#endif // CONFIG_DDT_INTER
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 3, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -295,7 +308,11 @@
{ 7, 8, 9, 12, 10, 11, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6 },
};
+#if CONFIG_DDT_INTER
+static const int av1_ext_tx_inv[EXT_TX_SET_TYPES][TX_TYPES_TRIG] = {
+#else
static const int av1_ext_tx_inv[EXT_TX_SET_TYPES][TX_TYPES] = {
+#endif // CONFIG_DDT_INTER
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 9, 0, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
diff --git a/av1/common/enums.h b/av1/common/enums.h
index f84ea5a..f2b097c 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -362,6 +362,9 @@
ADST_1D,
FLIPADST_1D,
IDTX_1D,
+#if CONFIG_DDT_INTER
+ DDT1_1D,
+#endif // CONFIG_DDT_INTER
TX_TYPES_1D,
} UENUM1BYTE(TX_TYPE_1D);
@@ -382,8 +385,22 @@
H_ADST, // Identity in vertical, ADST in horizontal
V_FLIPADST, // FLIPADST in vertical, identity in horizontal
H_FLIPADST, // Identity in vertical, FLIPADST in horizontal
+#if CONFIG_DDT_INTER
+ DDT_DDT, // DDT in both horizontal and vertical
+ DDT_DCT, // DDT in vertical, DCT in horizontal
+ DCT_DDT, // DCT in vertical, DDT in horizontal
+ FLIPDDT_FLIPDDT, // flipped DDT in both horizontal and vertical
+ FLIPDDT_DCT, // flipped DDT in vertical, DCT in horizontal
+ DCT_FLIPDDT, // DCT in vertical, flipped DDT in horizontal
+ FLIPDDT_DDT, // flipped DDT in vertical, DDT in horizontal
+ DDT_FLIPDDT, // DDT in vertical, flipped DDT in horizontal
+#endif // CONFIG_DDT_INTER
TX_TYPES,
- DCT_ADST_TX_MASK = 0x000F, // Either DCT or ADST in each direction
+#if CONFIG_DDT_INTER
+ TX_TYPES_TRIG = DDT_DDT, // Trignometric transforms (16)
+ DDT_TYPES = TX_TYPES - TX_TYPES_TRIG, // data-driven transforms (8)
+#endif // CONFIG_DDT_INTER
+ DCT_ADST_TX_MASK = 0x000F, // Either DCT or ADST in each direction
} UENUM1BYTE(TX_TYPE);
enum {
@@ -409,8 +426,14 @@
EXT_TX_SET_DTT4_IDTX_1DDCT,
// Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver DCT (2)
EXT_TX_SET_DTT9_IDTX_1DDCT,
+#if CONFIG_DDT_INTER
+ // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6)
+ // + DCT w/ 2 DDTs (4) + 2 DDTs (4)
+ EXT_TX_SET_ALL24,
+#else
// Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6)
EXT_TX_SET_ALL16,
+#endif // CONFIG_DDT_INTER
EXT_TX_SET_TYPES
} UENUM1BYTE(TxSetType);
diff --git a/av1/common/idct.c b/av1/common/idct.c
index 659bb0b..7f97bf6 100644
--- a/av1/common/idct.c
+++ b/av1/common/idct.c
@@ -354,7 +354,9 @@
av1_inv_stxfm(dqcoeff, &txfm_param);
#endif
-#if CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ av1_highbd_inv_txfm_add_c(dqcoeff, dst, stride, &txfm_param);
+#elif CONFIG_DST_32X32
if ((tx_size_wide[tx_size] == 16 || tx_size_high[tx_size] == 16 ||
tx_size_wide[tx_size] == 32 || tx_size_high[tx_size] == 32) &&
allowed_tx_mask)
@@ -369,7 +371,7 @@
av1_highbd_inv_txfm_add(dqcoeff, dst, stride, &txfm_param);
#else
av1_highbd_inv_txfm_add(dqcoeff, dst, stride, &txfm_param);
-#endif // CONFIG_DST7_16X16 && CONFIG_DST_32X32
+#endif // CONFIG_DDT_INTER
}
// Inverse secondary transform
diff --git a/av1/common/quant_common.c b/av1/common/quant_common.c
index 8a961c2..3f1c6d5 100644
--- a/av1/common/quant_common.c
+++ b/av1/common/quant_common.c
@@ -244,13 +244,18 @@
// Returns true if the tx_type corresponds to non-identity transform in both
// horizontal and vertical directions.
-#if CONFIG_IST
static INLINE bool is_2d_transform(TX_TYPE tx_type) {
+#if CONFIG_DDT_INTER && CONFIG_IST
+ return (get_primary_tx_type(tx_type) < IDTX ||
+ get_primary_tx_type(tx_type) >= DDT_DDT);
+#elif CONFIG_DDT_INTER
+ return (tx_type < IDTX || tx_type >= DDT_DDT);
+#elif CONFIG_IST
return (get_primary_tx_type(tx_type) < IDTX);
-}
#else
-static INLINE bool is_2d_transform(TX_TYPE tx_type) { return (tx_type < IDTX); }
+ return tx_type < IDTX;
#endif
+}
const qm_val_t *av1_get_iqmatrix(const CommonQuantParams *quant_params,
const MACROBLOCKD *xd, int plane,
diff --git a/av1/common/scan.c b/av1/common/scan.c
index 476ec48..40c80ee 100644
--- a/av1/common/scan.c
+++ b/av1/common/scan.c
@@ -1693,6 +1693,16 @@
{ mcol_scan_4x4, av1_mcol_iscan_4x4 },
{ mrow_scan_4x4, av1_mrow_iscan_4x4 },
{ mcol_scan_4x4, av1_mcol_iscan_4x4 },
+#if CONFIG_DDT_INTER
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+ { default_scan_4x4, av1_default_iscan_4x4 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_8X8
@@ -1712,6 +1722,16 @@
{ mcol_scan_8x8, av1_mcol_iscan_8x8 },
{ mrow_scan_8x8, av1_mrow_iscan_8x8 },
{ mcol_scan_8x8, av1_mcol_iscan_8x8 },
+#if CONFIG_DDT_INTER
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+ { default_scan_8x8, av1_default_iscan_8x8 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_16X16
@@ -1731,6 +1751,16 @@
{ mcol_scan_16x16, av1_mcol_iscan_16x16 },
{ mrow_scan_16x16, av1_mrow_iscan_16x16 },
{ mcol_scan_16x16, av1_mcol_iscan_16x16 },
+#if CONFIG_DDT_INTER
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+ { default_scan_16x16, av1_default_iscan_16x16 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_32X32
@@ -1750,6 +1780,16 @@
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
{ mrow_scan_32x32, av1_mrow_iscan_32x32 },
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_64X64
@@ -1771,6 +1811,16 @@
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
{ mrow_scan_32x32, av1_mrow_iscan_32x32 },
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_4X8
@@ -1790,6 +1840,16 @@
{ mcol_scan_4x8, av1_mcol_iscan_4x8 },
{ mrow_scan_4x8, av1_mrow_iscan_4x8 },
{ mcol_scan_4x8, av1_mcol_iscan_4x8 },
+#if CONFIG_DDT_INTER
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+ { default_scan_4x8, av1_default_iscan_4x8 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_8X4
@@ -1809,6 +1869,16 @@
{ mcol_scan_8x4, av1_mcol_iscan_8x4 },
{ mrow_scan_8x4, av1_mrow_iscan_8x4 },
{ mcol_scan_8x4, av1_mcol_iscan_8x4 },
+#if CONFIG_DDT_INTER
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+ { default_scan_8x4, av1_default_iscan_8x4 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_8X16
@@ -1828,6 +1898,16 @@
{ mcol_scan_8x16, av1_mcol_iscan_8x16 },
{ mrow_scan_8x16, av1_mrow_iscan_8x16 },
{ mcol_scan_8x16, av1_mcol_iscan_8x16 },
+#if CONFIG_DDT_INTER
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+ { default_scan_8x16, av1_default_iscan_8x16 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_16X8
@@ -1847,6 +1927,16 @@
{ mcol_scan_16x8, av1_mcol_iscan_16x8 },
{ mrow_scan_16x8, av1_mrow_iscan_16x8 },
{ mcol_scan_16x8, av1_mcol_iscan_16x8 },
+#if CONFIG_DDT_INTER
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+ { default_scan_16x8, av1_default_iscan_16x8 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_16X32
@@ -1866,6 +1956,16 @@
{ mcol_scan_16x32, av1_mcol_iscan_16x32 },
{ mrow_scan_16x32, av1_mrow_iscan_16x32 },
{ mcol_scan_16x32, av1_mcol_iscan_16x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_32X16
@@ -1885,6 +1985,16 @@
{ mcol_scan_32x16, av1_mcol_iscan_32x16 },
{ mrow_scan_32x16, av1_mrow_iscan_32x16 },
{ mcol_scan_32x16, av1_mcol_iscan_32x16 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_32X64
@@ -1906,6 +2016,16 @@
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
{ mrow_scan_32x32, av1_mrow_iscan_32x32 },
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_64X32
@@ -1927,6 +2047,16 @@
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
{ mrow_scan_32x32, av1_mrow_iscan_32x32 },
{ mcol_scan_32x32, av1_mcol_iscan_32x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+ { default_scan_32x32, av1_default_iscan_32x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_4X16
@@ -1946,6 +2076,16 @@
{ mcol_scan_4x16, av1_mcol_iscan_4x16 },
{ mrow_scan_4x16, av1_mrow_iscan_4x16 },
{ mcol_scan_4x16, av1_mcol_iscan_4x16 },
+#if CONFIG_DDT_INTER
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+ { default_scan_4x16, av1_default_iscan_4x16 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_16X4
@@ -1965,6 +2105,16 @@
{ mcol_scan_16x4, av1_mcol_iscan_16x4 },
{ mrow_scan_16x4, av1_mrow_iscan_16x4 },
{ mcol_scan_16x4, av1_mcol_iscan_16x4 },
+#if CONFIG_DDT_INTER
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+ { default_scan_16x4, av1_default_iscan_16x4 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_8X32
@@ -1984,6 +2134,16 @@
{ mcol_scan_8x32, av1_mcol_iscan_8x32 },
{ mrow_scan_8x32, av1_mrow_iscan_8x32 },
{ mcol_scan_8x32, av1_mcol_iscan_8x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+ { default_scan_8x32, av1_default_iscan_8x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_32X8
@@ -2003,6 +2163,16 @@
{ mcol_scan_32x8, av1_mcol_iscan_32x8 },
{ mrow_scan_32x8, av1_mrow_iscan_32x8 },
{ mcol_scan_32x8, av1_mcol_iscan_32x8 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+ { default_scan_32x8, av1_default_iscan_32x8 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_16X64
@@ -2024,6 +2194,16 @@
{ mcol_scan_16x32, av1_mcol_iscan_16x32 },
{ mrow_scan_16x32, av1_mrow_iscan_16x32 },
{ mcol_scan_16x32, av1_mcol_iscan_16x32 },
+#if CONFIG_DDT_INTER
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+ { default_scan_16x32, av1_default_iscan_16x32 },
+#endif // CONFIG_DDT_INTER
},
{
// TX_64X16
@@ -2045,5 +2225,15 @@
{ mcol_scan_32x16, av1_mcol_iscan_32x16 },
{ mrow_scan_32x16, av1_mrow_iscan_32x16 },
{ mcol_scan_32x16, av1_mcol_iscan_32x16 },
+#if CONFIG_DDT_INTER
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+ { default_scan_32x16, av1_default_iscan_32x16 },
+#endif // CONFIG_DDT_INTER
},
};
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h
index 31db5d9..f60c992 100644
--- a/av1/common/txb_common.h
+++ b/av1/common/txb_common.h
@@ -42,6 +42,16 @@
TX_CLASS_HORIZ, // H_ADST
TX_CLASS_VERT, // V_FLIPADST
TX_CLASS_HORIZ, // H_FLIPADST
+#if CONFIG_DDT_INTER
+ TX_CLASS_2D, // DDT_DDT
+ TX_CLASS_2D, // DDT_DCT
+ TX_CLASS_2D, // DCT_DDT
+ TX_CLASS_2D, // FLIPDDT_FLIPDDT
+ TX_CLASS_2D, // FLIPDDT_DCT
+ TX_CLASS_2D, // DCT_FLIPDDT
+ TX_CLASS_2D, // FLIPDDT_DDT
+ TX_CLASS_2D, // DDT_FLIPDDT`
+#endif // CONFIG_DDT_INTER
};
static INLINE int get_txb_bwl(TX_SIZE tx_size) {
diff --git a/av1/common/x86/highbd_inv_txfm_sse4.c b/av1/common/x86/highbd_inv_txfm_sse4.c
index dc6dbaa..ec4c493 100644
--- a/av1/common/x86/highbd_inv_txfm_sse4.c
+++ b/av1/common/x86/highbd_inv_txfm_sse4.c
@@ -5100,6 +5100,9 @@
int bd = txfm_param->bd;
const TX_TYPE tx_type = txfm_param->tx_type;
const int32_t *src = cast_to_int32(input);
+#if CONFIG_DDT_INTER
+ av1_inv_txfm2d_add_8x8_c(src, CONVERT_TO_SHORTPTR(dest), stride, tx_type, bd);
+#else
switch (tx_type) {
case IDTX:
case H_DCT:
@@ -5117,6 +5120,7 @@
tx_type, bd);
break;
}
+#endif // CONFIG_DDT_INTER
}
void av1_highbd_inv_txfm_add_4x4_sse4_1(const tran_low_t *input, uint8_t *dest,
int stride,
@@ -5132,8 +5136,12 @@
av1_highbd_iwht4x4_add(input, dest, stride, eob, bd);
return;
}
+#if CONFIG_DDT_INTER
+ av1_inv_txfm2d_add_4x4_c(src, CONVERT_TO_SHORTPTR(dest), stride, tx_type, bd);
+#else
av1_inv_txfm2d_add_4x4_sse4_1(src, CONVERT_TO_SHORTPTR(dest), stride, tx_type,
bd);
+#endif // CONFIG_DDT_INTER
}
static void iidentity32_sse4_1(__m128i *in, __m128i *out, int bit, int do_cols,
int bd, int out_shift) {
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index fcddc28..4e74c41 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -820,9 +820,30 @@
const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
if (inter_block) {
- *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
- r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
- av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
+#if CONFIG_DDT_INTER
+ if (tx_set_type == EXT_TX_SET_ALL24) {
+ if (aom_read_symbol(r, ec_ctx->use_ddtx_inter_cdf[square_tx_size], 2,
+ ACCT_STR)) {
+ *tx_type =
+ DDT_DDT +
+ aom_read_symbol(r, ec_ctx->ddtx_type_inter_cdf[square_tx_size],
+ DDT_TYPES, ACCT_STR);
+#if CONFIG_IST
+ *tx_type |= (1 << 6);
+#endif // CONFIG_IST
+ } else {
+ *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
+ r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
+ av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
+ }
+ } else {
+#endif // CONFIG_DDT_INTER
+ *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
+ r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
+ av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
+#if CONFIG_DDT_INTER
+ }
+#endif
} else {
#if CONFIG_FORWARDSKIP
if (mbmi->fsc_mode[xd->tree_type == CHROMA_PART]) {
diff --git a/av1/encoder/av1_fwd_txfm1d.c b/av1/encoder/av1_fwd_txfm1d.c
index a5fb5e1..75613fe 100644
--- a/av1/encoder/av1_fwd_txfm1d.c
+++ b/av1/encoder/av1_fwd_txfm1d.c
@@ -674,6 +674,47 @@
av1_range_check_buf(stage, input, bf1, size, stage_range[stage]);
}
+#if CONFIG_DDT_INTER
+void av1_fklt4(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 4; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 4; j++) {
+ sum += input[j] * klt4_inter[i * 4 + j];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+
+void av1_fklt8(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 8; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 8; j++) {
+ sum += input[j] * klt8_inter[i * 8 + j];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+
+void av1_fklt16(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range) {
+ (void)cos_bit;
+ (void)stage_range;
+ for (int32_t i = 0; i < 16; i++) {
+ int32_t sum = 0;
+ for (int32_t j = 0; j < 16; j++) {
+ sum += input[j] * klt16_inter[i * 16 + j];
+ }
+ output[i] = ROUND_POWER_OF_TWO_SIGNED(sum, KLT_PREC_BITS);
+ }
+}
+#endif // CONFIG_DDT_INTER
+
void av1_fadst4(const int32_t *input, int32_t *output, int8_t cos_bit,
const int8_t *stage_range) {
int bit = cos_bit;
diff --git a/av1/encoder/av1_fwd_txfm1d.h b/av1/encoder/av1_fwd_txfm1d.h
index d41f81c..9f96341 100644
--- a/av1/encoder/av1_fwd_txfm1d.h
+++ b/av1/encoder/av1_fwd_txfm1d.h
@@ -15,6 +15,10 @@
#include "av1/common/av1_txfm.h"
+#if CONFIG_DDT_INTER
+#include "av1/common/ddtx_bases.h"
+#endif // CONFIG_DDT_INTER
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -47,6 +51,14 @@
const int8_t *stage_range);
void av1_fidentity32_c(const int32_t *input, int32_t *output, int8_t cos_bit,
const int8_t *stage_range);
+#if CONFIG_DDT_INTER
+void av1_fklt4(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+void av1_fklt8(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+void av1_fklt16(const int32_t *input, int32_t *output, int8_t cos_bit,
+ const int8_t *stage_range);
+#endif // CONFIG_DDT_INTER
#ifdef __cplusplus
}
#endif
diff --git a/av1/encoder/av1_fwd_txfm2d.c b/av1/encoder/av1_fwd_txfm2d.c
index 8d55e59..0989a1e 100644
--- a/av1/encoder/av1_fwd_txfm2d.c
+++ b/av1/encoder/av1_fwd_txfm2d.c
@@ -34,6 +34,11 @@
#if CONFIG_DST_32X32
case TXFM_TYPE_ADST32: return av1_fadst32;
#endif // CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ case TXFM_TYPE_DDT4: return av1_fklt4;
+ case TXFM_TYPE_DDT8: return av1_fklt8;
+ case TXFM_TYPE_DDT16: return av1_fklt16;
+#endif // CONFIG_DDT_INTER
case TXFM_TYPE_IDENTITY4: return av1_fidentity4_c;
case TXFM_TYPE_IDENTITY8: return av1_fidentity8_c;
case TXFM_TYPE_IDENTITY16: return av1_fidentity16_c;
@@ -388,20 +393,14 @@
#endif
static const int8_t *fwd_txfm_range_mult2_list[TXFM_TYPES] = {
- fdct4_range_mult2,
- fdct8_range_mult2,
- fdct16_range_mult2,
- fdct32_range_mult2,
- fdct64_range_mult2,
- fadst4_range_mult2,
- fadst8_range_mult2,
- fadst16_range_mult2,
- fidtx4_range_mult2,
- fidtx8_range_mult2,
- fidtx16_range_mult2,
- fidtx32_range_mult2
+ fdct4_range_mult2, fdct8_range_mult2, fdct16_range_mult2,
+ fdct32_range_mult2, fdct64_range_mult2, fadst4_range_mult2,
+ fadst8_range_mult2, fadst16_range_mult2, fidtx4_range_mult2,
+ fidtx8_range_mult2, fidtx16_range_mult2, fidtx32_range_mult2,
+#if CONFIG_DDT_INTER
+ fadst4_range_mult2, fadst8_range_mult2, fadst16_range_mult2,
+#endif // CONFIG_DDT_INTER
#if CONFIG_DST_32X32
- ,
fadst32_range_mult2,
#endif
};
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 1f8170d..da8c9a2 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1089,9 +1089,33 @@
assert(av1_ext_tx_used[tx_set_type][tx_type]);
#endif
if (is_inter) {
- aom_write_symbol(w, av1_ext_tx_ind[tx_set_type][tx_type],
- ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
- av1_num_ext_tx_set[tx_set_type]);
+#if CONFIG_DDT_INTER
+ if (tx_set_type == EXT_TX_SET_ALL24) {
+#if CONFIG_IST
+ TX_TYPE ptx_type = get_primary_tx_type(tx_type);
+#else
+ TX_TYPE ptx_type = tx_type;
+#endif
+ int is_ddtx = has_ddtx(ptx_type);
+ aom_write_symbol(w, is_ddtx, ec_ctx->use_ddtx_inter_cdf[square_tx_size],
+ 2);
+ if (is_ddtx) {
+ aom_write_symbol(w, ptx_type - DDT_DDT,
+ ec_ctx->ddtx_type_inter_cdf[square_tx_size],
+ DDT_TYPES);
+ } else {
+ aom_write_symbol(w, av1_ext_tx_ind[tx_set_type][ptx_type],
+ ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
+ av1_num_ext_tx_set[tx_set_type]);
+ }
+ } else {
+#endif // CONFIG_DDT_INTER
+ aom_write_symbol(w, av1_ext_tx_ind[tx_set_type][tx_type],
+ ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
+ av1_num_ext_tx_set[tx_set_type]);
+#if CONFIG_DDT_INTER
+ }
+#endif // CONFIG_DDT_INTER
} else {
#if CONFIG_FORWARDSKIP
if (mbmi->fsc_mode[xd->tree_type == CHROMA_PART]) {
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 918d4c7..6e97fee 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -828,11 +828,23 @@
//! txfm_partition_cost
int txfm_partition_cost[TXFM_PARTITION_CONTEXTS][2];
#endif // CONFIG_NEW_TX_PARTITION
+#if CONFIG_DDT_INTER
+ //! use_ddtx_inter_costs
+ int use_ddtx_inter_costs[EXT_TX_SIZES][2];
+ //! ddtx_type_inter_costs
+ int ddtx_type_inter_costs[EXT_TX_SIZES][DDT_TYPES];
+ //! inter_tx_type_costs
+ int inter_tx_type_costs[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES_TRIG];
+ //! intra_tx_type_costs
+ int intra_tx_type_costs[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
+ [TX_TYPES_TRIG];
+#else
//! inter_tx_type_costs
int inter_tx_type_costs[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES];
//! intra_tx_type_costs
int intra_tx_type_costs[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
[TX_TYPES];
+#endif // CONFIG_DDT_INTER
/**@}*/
/*****************************************************************************
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index aef4637..3072f2f 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1286,9 +1286,17 @@
unsigned int delta_lf_multi[FRAME_LF_COUNT][DELTA_LF_PROBS][2];
unsigned int delta_lf[DELTA_LF_PROBS][2];
+#if CONFIG_DDT_INTER
+ unsigned int use_ddtx_inter[EXT_TX_SIZES][2];
+ unsigned int ddtx_type_inter[EXT_TX_SIZES][DDT_TYPES];
+ unsigned int inter_ext_tx[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES_TRIG];
+ unsigned int intra_ext_tx[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
+ [TX_TYPES_TRIG];
+#else
unsigned int inter_ext_tx[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES];
unsigned int intra_ext_tx[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
[TX_TYPES];
+#endif // CONFIG_DDT_INTER
unsigned int filter_intra_mode[FILTER_INTRA_MODES];
unsigned int filter_intra[BLOCK_SIZES_ALL][2];
unsigned int switchable_restore[RESTORE_SWITCHABLE_TYPES];
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index e21d998..85eebe2 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -849,9 +849,34 @@
const int ext_tx_set =
get_ext_tx_set(tx_size, is_inter, reduced_tx_set_used);
if (is_inter) {
+#if CONFIG_DDT_INTER
+ const TxSetType tx_set_type =
+ av1_get_ext_tx_set_type(tx_size, is_inter, reduced_tx_set_used);
+ if (tx_set_type == EXT_TX_SET_ALL24) {
+#if CONFIG_IST
+ TX_TYPE ptx_type = get_primary_tx_type(tx_type);
+#else
+ TX_TYPE ptx_type = tx_type;
+#endif // CONFIG_IST
+ int is_ddtx = has_ddtx(ptx_type);
+ int use_ddtx_cost =
+ x->mode_costs.use_ddtx_inter_costs[square_tx_size][is_ddtx];
+ int tx_type_cost =
+ is_ddtx
+ ? x->mode_costs
+ .ddtx_type_inter_costs[square_tx_size][ptx_type - DDT_DDT]
+ : x->mode_costs.inter_tx_type_costs[ext_tx_set][square_tx_size]
+ [ptx_type];
+ return use_ddtx_cost + tx_type_cost;
+ } else {
+ return x->mode_costs
+ .inter_tx_type_costs[ext_tx_set][square_tx_size][tx_type];
+ }
+#else
if (ext_tx_set > 0)
return x->mode_costs
.inter_tx_type_costs[ext_tx_set][square_tx_size][tx_type];
+#endif // CONFIG_DDT_INTER
} else {
if (ext_tx_set > 0) {
PREDICTION_MODE intra_dir;
@@ -2084,13 +2109,56 @@
av1_get_ext_tx_set_type(tx_size, is_inter, reduced_tx_set_used);
if (is_inter) {
if (allow_update_cdf) {
- update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
- av1_ext_tx_ind[tx_set_type][tx_type],
- av1_num_ext_tx_set[tx_set_type]);
+#if CONFIG_DDT_INTER
+ if (tx_set_type == EXT_TX_SET_ALL24) {
+#if CONFIG_IST
+ TX_TYPE ptx_type = get_primary_tx_type(tx_type);
+#else
+ TX_TYPE ptx_type = tx_type;
+#endif // CONFIG_IST
+ int is_ddtx = has_ddtx(ptx_type);
+ update_cdf(fc->use_ddtx_inter_cdf[txsize_sqr_map[tx_size]], is_ddtx,
+ 2);
+ if (is_ddtx) {
+ update_cdf(fc->ddtx_type_inter_cdf[txsize_sqr_map[tx_size]],
+ ptx_type - DDT_DDT, DDT_TYPES);
+ } else {
+ update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
+ av1_ext_tx_ind[tx_set_type][ptx_type],
+ av1_num_ext_tx_set[tx_set_type]);
+ }
+ } else {
+#endif // CONFIG_DDT_INTER
+ update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
+ av1_ext_tx_ind[tx_set_type][tx_type],
+ av1_num_ext_tx_set[tx_set_type]);
+#if CONFIG_DDT_INTER
+ }
+#endif
}
#if CONFIG_ENTROPY_STATS
- ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
- [av1_ext_tx_ind[tx_set_type][tx_type]];
+#if CONFIG_DDT_INTER
+ if (tx_set_type == EXT_TX_SET_ALL24) {
+#if CONFIG_IST
+ TX_TYPE ptx_type = get_primary_tx_type(tx_type);
+#else
+ TX_TYPE ptx_type = tx_type;
+#endif // CONFIG_IST
+ int is_ddtx = has_ddtx(ptx_type);
+ ++counts->use_ddtx_inter[txsize_sqr_map[tx_size]][is_ddtx];
+ if (is_ddtx)
+ ++counts->ddtx_type_inter[txsize_sqr_map[tx_size]]
+ [ptx_type - DDT_DDT];
+ else
+ ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
+ [av1_ext_tx_ind[tx_set_type][ptx_type]];
+ } else {
+#endif
+ ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
+ [av1_ext_tx_ind[tx_set_type][tx_type]];
+#if CONFIG_DDT_INTER
+ }
+#endif
#endif // CONFIG_ENTROPY_STATS
} else {
#if CONFIG_FORWARDSKIP
diff --git a/av1/encoder/hybrid_fwd_txfm.c b/av1/encoder/hybrid_fwd_txfm.c
index 09248f4..5ef2ff8 100644
--- a/av1/encoder/hybrid_fwd_txfm.c
+++ b/av1/encoder/hybrid_fwd_txfm.c
@@ -91,21 +91,35 @@
av1_highbd_fwht4x4(src_diff, coeff, diff_stride);
return;
}
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_4x4_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#else
av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#endif // CCONFIG_DDT_INTER
}
static void highbd_fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_4x8_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#else
av1_fwd_txfm2d_4x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_8x4_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#else
av1_fwd_txfm2d_8x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
@@ -113,7 +127,9 @@
int32_t *dst_coeff = (int32_t *)coeff;
const TX_TYPE tx_type = txfm_param->tx_type;
const int bd = txfm_param->bd;
-#if CONFIG_DST7_16X16
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_8x16_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#elif CONFIG_DST7_16X16
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
if (allowed_tx_mask)
@@ -122,7 +138,7 @@
av1_fwd_txfm2d_8x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
#else
av1_fwd_txfm2d_8x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
-#endif // CONFIG_DST7_16X16
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
@@ -130,7 +146,9 @@
int32_t *dst_coeff = (int32_t *)coeff;
const TX_TYPE tx_type = txfm_param->tx_type;
const int bd = txfm_param->bd;
-#if CONFIG_DST7_16X16
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_16x8_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#elif CONFIG_DST7_16X16
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
if (allowed_tx_mask)
@@ -139,13 +157,16 @@
av1_fwd_txfm2d_16x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
#else
av1_fwd_txfm2d_16x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
-#endif // CONFIG_DST7_16X16
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_16x32_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST_32X32
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -159,13 +180,16 @@
assert(txfm_param->tx_type == DCT_DCT || txfm_param->tx_type == IDTX);
av1_fwd_txfm2d_16x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST_32X32
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_32x16_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST_32X32
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -179,13 +203,16 @@
assert(txfm_param->tx_type == DCT_DCT || txfm_param->tx_type == IDTX);
av1_fwd_txfm2d_32x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST_32X32
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST7_16X16
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_16x4_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST7_16X16
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -198,13 +225,16 @@
#else
av1_fwd_txfm2d_16x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST7_16X16
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST7_16X16
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_4x16_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST7_16X16
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -217,13 +247,16 @@
#else
av1_fwd_txfm2d_4x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST7_16X16
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_32x8_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST_32X32
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -236,13 +269,16 @@
#else
av1_fwd_txfm2d_32x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST_32X32
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
int32_t *dst_coeff = (int32_t *)coeff;
-#if CONFIG_DST_32X32
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_8x32_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
+ txfm_param->bd);
+#elif CONFIG_DST_32X32
const TX_TYPE tx_type = txfm_param->tx_type;
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
@@ -255,7 +291,7 @@
#else
av1_fwd_txfm2d_8x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
-#endif // CONFIG_DST_32X32
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
@@ -263,7 +299,11 @@
int32_t *dst_coeff = (int32_t *)coeff;
const TX_TYPE tx_type = txfm_param->tx_type;
const int bd = txfm_param->bd;
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_8x8_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#else
av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
@@ -271,7 +311,9 @@
int32_t *dst_coeff = (int32_t *)coeff;
const TX_TYPE tx_type = txfm_param->tx_type;
const int bd = txfm_param->bd;
-#if CONFIG_DST7_16X16
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_16x16_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
+#elif CONFIG_DST7_16X16
uint16_t allowed_tx_mask = 0xF1FE;
allowed_tx_mask &= (1 << tx_type);
if (allowed_tx_mask)
@@ -280,7 +322,7 @@
av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
#else
av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
-#endif // CONFIG_DST7_16X16
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
@@ -323,7 +365,11 @@
assert(txfm_param->tx_type == DCT_DCT);
int32_t *dst_coeff = (int32_t *)coeff;
const int bd = txfm_param->bd;
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_16x64_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
+#else
av1_fwd_txfm2d_16x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_64x16(const int16_t *src_diff, tran_low_t *coeff,
@@ -331,7 +377,11 @@
assert(txfm_param->tx_type == DCT_DCT);
int32_t *dst_coeff = (int32_t *)coeff;
const int bd = txfm_param->bd;
+#if CONFIG_DDT_INTER
+ av1_fwd_txfm2d_64x16_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
+#else
av1_fwd_txfm2d_64x16(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
+#endif // CONFIG_DDT_INTER
}
static void highbd_fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
@@ -344,6 +394,9 @@
void av1_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff, int diff_stride,
TxfmParam *txfm_param) {
+#if CONFIG_DDT_INTER
+ av1_lowbd_fwd_txfm_c(src_diff, coeff, diff_stride, txfm_param);
+#else
if (txfm_param->bd == 8) {
#if CONFIG_DST7_16X16 || CONFIG_DST_32X32
const TX_TYPE tx_type = txfm_param->tx_type;
@@ -372,6 +425,7 @@
} else {
av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
}
+#endif // CONFIG_DDT_INTER
}
void av1_lowbd_fwd_txfm_c(const int16_t *src_diff, tran_low_t *coeff,
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index bda46a8..73684e0 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -84,7 +84,11 @@
{
// Inter
EXT_TX_SET_DCTONLY,
+#if CONFIG_DDT_INTER
+ EXT_TX_SET_ALL24,
+#else
EXT_TX_SET_ALL16,
+#endif // CONFIG_DDT_INTER
EXT_TX_SET_DTT9_IDTX_1DDCT,
EXT_TX_SET_DCT_IDTX,
},
@@ -280,6 +284,16 @@
}
}
}
+#if CONFIG_DDT_INTER
+ for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
+ av1_cost_tokens_from_cdf(mode_costs->ddtx_type_inter_costs[i],
+ fc->ddtx_type_inter_cdf[i], NULL);
+ }
+ for (int s = 0; s < EXT_TX_SIZES; ++s) {
+ av1_cost_tokens_from_cdf(mode_costs->use_ddtx_inter_costs[s],
+ fc->use_ddtx_inter_cdf[s], NULL);
+ }
+#endif // CONFIG_DDT_INTER
#if !CONFIG_AIMC
for (i = 0; i < PARTITION_STRUCTURE_NUM; ++i) {
for (j = 0; j < DIRECTIONAL_MODES; ++j) {
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 8b74a2d..9489963 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -70,7 +70,11 @@
#endif
txfm_param.tx_size = tx_size;
txfm_param.lossless = 0;
+#if CONFIG_DDT_INTER
+ txfm_param.tx_set_type = EXT_TX_SET_ALL24;
+#else
txfm_param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
txfm_param.bd = bit_depth;
av1_fwd_txfm(src_diff, coeff, bw, &txfm_param);
diff --git a/av1/encoder/tx_search.c b/av1/encoder/tx_search.c
index af438a9..3216e4a 100644
--- a/av1/encoder/tx_search.c
+++ b/av1/encoder/tx_search.c
@@ -1408,7 +1408,11 @@
// to ensure we can try ones even outside of ext_tx_set of current block
// this function should only be called for size < 16
assert(txsize_sqr_up_map[tx_size] <= TX_16X16);
+#if CONFIG_DDT_INTER
+ txfm_param.tx_set_type = EXT_TX_SET_ALL24;
+#else
txfm_param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
int rate_cost = 0;
int64_t dist = 0, sse = 0;
@@ -1482,7 +1486,12 @@
// combine rd_h and rd_v to prune tx candidates
int i_v, i_h;
int64_t rds[16];
+#if CONFIG_DDT_INTER
+ // Pruning is not applied to DDT for now.
+ int num_cand = 0, last = TX_TYPES_TRIG - 1;
+#else
int num_cand = 0, last = TX_TYPES - 1;
+#endif // CONFIG_DDT_INTER
for (int i = 0; i < 16; i++) {
i_v = sel_pattern_v[i];
@@ -1522,10 +1531,19 @@
const AV1_COMMON *cm = &cpi->common;
int tx_type;
+#if CONFIG_DDT_INTER
+ // Pruning is not applied to DDT for now.
+ int64_t rds[TX_TYPES_TRIG];
+#else
int64_t rds[TX_TYPES];
+#endif // CONFIG_DDT_INTER
int num_cand = 0;
+#if CONFIG_DDT_INTER
+ int last = TX_TYPES_TRIG - 1;
+#else
int last = TX_TYPES - 1;
+#endif // CONFIG_DDT_INTER
TxfmParam txfm_param;
QUANT_PARAM quant_param;
@@ -1537,7 +1555,11 @@
av1_setup_quant(tx_size, 1, AV1_XFORM_QUANT_B, cpi->oxcf.q_cfg.quant_b_adapt,
&quant_param);
+#if CONFIG_DDT_INTER
+ for (int idx = 0; idx < TX_TYPES_TRIG; idx++) {
+#else
for (int idx = 0; idx < TX_TYPES; idx++) {
+#endif // CONFIG_DDT_INTER
tx_type = idx;
int rate_cost = 0;
int64_t dist = 0, sse = 0;
@@ -1681,7 +1703,11 @@
{ 4, 1 }, { 6, 3 }, { 9, 6 }, { 9, 6 }, { 12, 9 }
};
int pruning_aggressiveness = 0;
+#if CONFIG_DDT_INTER
+ if (tx_set_type == EXT_TX_SET_ALL24)
+#else
if (tx_set_type == EXT_TX_SET_ALL16)
+#endif // CONFIG_DDT_INTER
pruning_aggressiveness =
prune_aggr_table[prune_2d_txfm_mode - TX_TYPE_PRUNE_1][0];
else if (tx_set_type == EXT_TX_SET_DTT9_IDTX_1DDCT)
@@ -1765,7 +1791,11 @@
FLIPADST_DCT, FLIPADST_ADST, FLIPADST_FLIPADST, V_FLIPADST,
H_DCT, H_ADST, H_FLIPADST, IDTX
};
+#if CONFIG_DDT_INTER
+ if (tx_set_type != EXT_TX_SET_ALL24 &&
+#else
if (tx_set_type != EXT_TX_SET_ALL16 &&
+#endif // CONFIG_DDT_INTER
tx_set_type != EXT_TX_SET_DTT9_IDTX_1DDCT)
return;
#if CONFIG_NN_V2
@@ -1828,7 +1858,11 @@
float sum_score = 0.0;
// Calculate sum of allowed tx type score and Populate allow bit mask based
// on score_thresh and allowed_tx_mask
+#if CONFIG_DDT_INTER
+ for (int tx_idx = 0; tx_idx < TX_TYPES_TRIG; tx_idx++) {
+#else
for (int tx_idx = 0; tx_idx < TX_TYPES; tx_idx++) {
+#endif // CONFIG_DDT_INTER
int allow_tx_type = *allowed_tx_mask & (1 << tx_type_table_2D[tx_idx]);
if (scores_2D[tx_idx] > max_score && allow_tx_type) {
max_score = scores_2D[tx_idx];
@@ -1848,7 +1882,11 @@
sum_score += scores_2D[max_score_i];
}
// Sort tx type probability of all types
+#if CONFIG_DDT_INTER
+ sort_probability(scores_2D, tx_type_table_2D, TX_TYPES_TRIG);
+#else
sort_probability(scores_2D, tx_type_table_2D, TX_TYPES);
+#endif // CONFIG_DDT_INTER
// Enable more pruning based on tx type probability and number of allowed tx
// types
@@ -1858,7 +1896,11 @@
int tx_idx, tx_count = 0;
const float inv_sum_score = 100 / sum_score;
// Get allowed tx types based on sorted probability score and tx count
+#if CONFIG_DDT_INTER
+ for (tx_idx = 0; tx_idx < TX_TYPES_TRIG; tx_idx++) {
+#else
for (tx_idx = 0; tx_idx < TX_TYPES; tx_idx++) {
+#endif // CONFIG_DDT_INTER
// Skip the tx type which has more than 30% of cumulative
// probability and allowed tx type count is more than 2
if (score_ratio > 30.0 && tx_count >= 2) break;
@@ -1874,7 +1916,11 @@
}
}
// Set remaining tx types as pruned
+#if CONFIG_DDT_INTER
+ for (; tx_idx < TX_TYPES_TRIG; tx_idx++)
+#else
for (; tx_idx < TX_TYPES; tx_idx++)
+#endif // CONFIG_DDT_INTER
allow_bitmask &= ~(1 << tx_type_table_2D[tx_idx]);
}
memcpy(txk_map, tx_type_table_2D, sizeof(tx_type_table_2D));
@@ -2045,7 +2091,11 @@
uint16_t prune = 0;
int max_prob = -1;
int max_idx = 0;
+#if CONFIG_DDT_INTER
+ for (i = 0; i < TX_TYPES_TRIG; i++) {
+#else
for (i = 0; i < TX_TYPES; i++) {
+#endif // CONFIG_DDT_INTER
if (tx_type_probs[i] > max_prob && (allowed_tx_mask & (1 << i))) {
max_prob = tx_type_probs[i];
max_idx = i;
@@ -2055,7 +2105,11 @@
if ((prune >> max_idx) & 0x01) prune &= ~(1 << max_idx);
allowed_tx_mask &= (~prune);
}
+#if CONFIG_DDT_INTER
+ for (i = 0; i < TX_TYPES_TRIG; i++) {
+#else
for (i = 0; i < TX_TYPES; i++) {
+#endif // CONFIG_DDT_INTER
if (allowed_tx_mask & (1 << i)) num_allowed++;
}
assert(num_allowed > 0);
@@ -2356,9 +2410,16 @@
// txk_allowed = TX_TYPES: >1 tx types are allowed
// txk_allowed < TX_TYPES: only that specific tx type is allowed.
TX_TYPE txk_allowed = TX_TYPES;
+#if CONFIG_DDT_INTER
+ int txk_map[TX_TYPES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
+ const TxSetType tx_set_type = av1_get_ext_tx_set_type(
+ tx_size, is_inter, cm->features.reduced_tx_set_used);
+#else
int txk_map[TX_TYPES] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
+#endif // CONFIG_DDT_INTER
const int dequant_shift = xd->bd - 5;
const int qstep =
@@ -2495,7 +2556,13 @@
const int max_stx = xd->enable_ist ? 4 : 1;
for (int stx = 0; stx < max_stx; ++stx) {
TX_TYPE tx_type = (TX_TYPE)txk_map[idx];
+#if CONFIG_DDT_INTER
+ int is_ddtx = has_ddtx(tx_type);
+ if (!is_ddtx && !(allowed_tx_mask & (1 << tx_type))) continue;
+ if (is_ddtx && !av1_ext_tx_used[tx_set_type][tx_type]) continue;
+#else
if (!(allowed_tx_mask & (1 << tx_type))) continue;
+#endif // CONFIG_DDT_INTER
const PREDICTION_MODE intra_mode =
(plane == AOM_PLANE_Y) ? mbmi->mode : get_uv_mode(mbmi->uv_mode);
const int filter = mbmi->filter_intra_mode_info.use_filter_intra;
@@ -2510,11 +2577,20 @@
xd->lossless[mbmi->segment_id]);
if (skip_stx && stx) continue;
tx_type += (stx << 4);
+#if CONFIG_DDT_INTER
+ tx_type += (is_ddtx << 6);
+#endif // CONFIG_DDT_INTER
txfm_param.tx_type = get_primary_tx_type(tx_type);
txfm_param.sec_tx_type = stx;
#else
const TX_TYPE tx_type = (TX_TYPE)txk_map[idx];
+#if CONFIG_DDT_INTER
+ int is_ddtx = has_ddtx(tx_type);
+ if (!is_ddtx && !(allowed_tx_mask & (1 << tx_type))) continue;
+ if (is_ddtx && !av1_ext_tx_used[tx_set_type][tx_type]) continue;
+#else
if (!(allowed_tx_mask & (1 << tx_type))) continue;
+#endif // CONFIG_DDT_INTER
txfm_param.tx_type = tx_type;
#endif
if (av1_use_qmatrix(&cm->quant_params, xd, mbmi->segment_id)) {
diff --git a/av1/encoder/x86/av1_fwd_txfm2d_sse4.c b/av1/encoder/x86/av1_fwd_txfm2d_sse4.c
index 8032fb7..57cb7a3 100644
--- a/av1/encoder/x86/av1_fwd_txfm2d_sse4.c
+++ b/av1/encoder/x86/av1_fwd_txfm2d_sse4.c
@@ -355,6 +355,10 @@
void av1_lowbd_fwd_txfm_sse4_1(const int16_t *src_diff, tran_low_t *coeff,
int diff_stride, TxfmParam *txfm_param) {
FwdTxfm2dFunc fwd_txfm2d_func = fwd_txfm2d_func_ls[txfm_param->tx_size];
+#if CONFIG_DDT_INTER
+ (void)fwd_txfm2d_func; // this is added to silence a warning
+ av1_lowbd_fwd_txfm_c(src_diff, coeff, diff_stride, txfm_param);
+#else
if ((fwd_txfm2d_func == NULL) ||
(txfm_param->lossless && txfm_param->tx_size == TX_4X4)) {
av1_lowbd_fwd_txfm_c(src_diff, coeff, diff_stride, txfm_param);
@@ -362,4 +366,5 @@
fwd_txfm2d_func(src_diff, coeff, diff_stride, txfm_param->tx_type,
txfm_param->bd);
}
+#endif // CONFIG_DDT_INTER
}
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index 78fb105..46c4535 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -206,6 +206,8 @@
# Primary Transforms
set_aom_config_var(CONFIG_DST7_16X16 0 NUMBER "AV2 DST7 16x16 experiment flag.")
set_aom_config_var(CONFIG_DST_32X32 0 NUMBER "AV2 DST7 32x32 experiment flag.")
+set_aom_config_var(CONFIG_DDT_INTER 0 NUMBER
+ "AV2 data-driven inter transform experiment flag.")
#
# Variables in this section control optional features of the build system.
#
diff --git a/test/av1_fwd_txfm2d_test.cc b/test/av1_fwd_txfm2d_test.cc
index 63f6c99..9e1cf60 100644
--- a/test/av1_fwd_txfm2d_test.cc
+++ b/test/av1_fwd_txfm2d_test.cc
@@ -271,7 +271,11 @@
}
param.tx_type = (TX_TYPE)tx_type;
param.tx_size = (TX_SIZE)tx_size;
+#if CONFIG_DDT_INTER
+ param.tx_set_type = EXT_TX_SET_ALL24;
+#else
param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
param.bd = bd;
ref_func(input, ref_output, input_stride, (TX_TYPE)tx_type, bd);
target_func(input, output, input_stride, ¶m);
@@ -321,7 +325,11 @@
param.tx_type = (TX_TYPE)tx_type;
param.tx_size = (TX_SIZE)tx_size;
+#if CONFIG_DDT_INTER
+ param.tx_set_type = EXT_TX_SET_ALL24;
+#else
param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
param.bd = bd;
aom_usec_timer ref_timer, test_timer;
@@ -475,7 +483,11 @@
}
param.tx_type = (TX_TYPE)tx_type;
param.tx_size = (TX_SIZE)tx_size;
+#if CONFIG_DDT_INTER
+ param.tx_set_type = EXT_TX_SET_ALL24;
+#else
param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
param.bd = bd;
ref_func(input, ref_output, input_stride, (TX_TYPE)tx_type, bd);
@@ -529,7 +541,11 @@
param.tx_type = (TX_TYPE)tx_type;
param.tx_size = (TX_SIZE)tx_size;
+#if CONFIG_DDT_INTER
+ param.tx_set_type = EXT_TX_SET_ALL24;
+#else
param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
param.bd = bd;
aom_usec_timer ref_timer, test_timer;
diff --git a/test/av1_highbd_iht_test.cc b/test/av1_highbd_iht_test.cc
index 2630655..ef275db 100644
--- a/test/av1_highbd_iht_test.cc
+++ b/test/av1_highbd_iht_test.cc
@@ -237,7 +237,11 @@
txfm_param.tx_size = tx_size_;
txfm_param.lossless = 0;
txfm_param.bd = bit_depth_;
+#if CONFIG_DDT_INTER
+ txfm_param.tx_set_type = EXT_TX_SET_ALL24;
+#else
txfm_param.tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
for (int cnt = 0; cnt < randTimes; ++cnt) {
for (int r = 0; r < BLK_WIDTH; ++r) {
diff --git a/test/av1_txfm_test.h b/test/av1_txfm_test.h
index c9c6bce..ca0a613 100644
--- a/test/av1_txfm_test.h
+++ b/test/av1_txfm_test.h
@@ -92,7 +92,11 @@
} else if (tx_size_sqr_up == TX_32X32) {
tx_set_type = EXT_TX_SET_DCT_IDTX;
} else {
+#if CONFIG_DDT_INTER
+ tx_set_type = EXT_TX_SET_ALL24;
+#else
tx_set_type = EXT_TX_SET_ALL16;
+#endif // CONFIG_DDT_INTER
}
return av1_ext_tx_used[tx_set_type][tx_type] != 0;
}
diff --git a/tools/aom_entropy_optimizer.c b/tools/aom_entropy_optimizer.c
index c190df1..ce10657 100644
--- a/tools/aom_entropy_optimizer.c
+++ b/tools/aom_entropy_optimizer.c
@@ -356,11 +356,31 @@
"static const aom_cdf_prob default_partition_cdf[PARTITION_CONTEXTS]"
"[CDF_SIZE(EXT_PARTITION_TYPES)]");
+#if CONFIG_DDT_INTER
+ cts_each_dim[0] = EXT_TX_SIZES;
+ cts_each_dim[1] = 2;
+ optimize_cdf_table(
+ &fc.use_ddtx_inter[0][0], probsfile, 2, cts_each_dim,
+ "static const aom_cdf_prob default_use_ddtx_inter[EXT_TX_SIZES]"
+ "[CDF_SIZE(2)]");
+
+ cts_each_dim[0] = EXT_TX_SIZES;
+ cts_each_dim[1] = DDT_TYPES;
+ optimize_cdf_table(&fc.ddtx_type_inter[0][0], probsfile, 2, cts_each_dim,
+ "static const aom_cdf_prob\n"
+ "default_ddtx_type_inter[EXT_TX_SIZES]"
+ "[CDF_SIZE(DDT_TYPES)]");
+#endif // CONFIG_DDT_INTER
+
/* tx type */
cts_each_dim[0] = EXT_TX_SETS_INTRA;
cts_each_dim[1] = EXT_TX_SIZES;
cts_each_dim[2] = INTRA_MODES;
+#if CONFIG_DDT_INTER
+ cts_each_dim[3] = TX_TYPES_TRIG;
+#else
cts_each_dim[3] = TX_TYPES;
+#endif // CONFIG_DDT_INTER
#if CONFIG_FORWARDSKIP
int intra_ext_tx_types_each_ctx[EXT_TX_SETS_INTRA] = { 0, INTRA_TX_SET1,
INTRA_TX_SET2 };
@@ -380,7 +400,11 @@
cts_each_dim[0] = EXT_TX_SETS_INTER;
cts_each_dim[1] = EXT_TX_SIZES;
+#if CONFIG_DDT_INTER
+ cts_each_dim[2] = TX_TYPES_TRIG;
+#else
cts_each_dim[2] = TX_TYPES;
+#endif // CONFIG_DDT_INTER
int inter_ext_tx_types_each_ctx[EXT_TX_SETS_INTER] = { 0, 16, 12, 2 };
optimize_cdf_table_var_modes_3d(
&fc.inter_ext_tx[0][0][0], probsfile, 3, cts_each_dim,