Enable rectangular transforms for UV

Uses an array to map block sizes, y tx sizes, and subsampling
factors to various transform sizes for UV.

Results improve by 0.1-0.2%

Change-Id: Icb58fd96bc7c01a72cbf1332fe2be4d55a0feedc
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 8fcaa60..f035bb5 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -684,25 +684,18 @@
 
 void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);
 
-static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
-                                          int xss, int yss) {
-  if (bsize < BLOCK_8X8) {
-    return TX_4X4;
-  } else {
-    const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss];
-    return AOMMIN(txsize_sqr_map[y_tx_size], max_txsize_lookup[plane_bsize]);
-  }
-}
-
 static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi,
                                      const struct macroblockd_plane *pd) {
+  TX_SIZE uv_txsize;
 #if CONFIG_SUPERTX
   if (supertx_enabled(mbmi))
     return uvsupertx_size_lookup[txsize_sqr_map[mbmi->tx_size]]
                                 [pd->subsampling_x][pd->subsampling_y];
 #endif  // CONFIG_SUPERTX
-  return get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type, pd->subsampling_x,
-                             pd->subsampling_y);
+  uv_txsize = uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][pd->subsampling_x]
+                              [pd->subsampling_y];
+  assert(uv_txsize != TX_INVALID);
+  return uv_txsize;
 }
 
 static INLINE BLOCK_SIZE
diff --git a/av1/common/common_data.h b/av1/common/common_data.h
index f86e1f7..450d962 100644
--- a/av1/common/common_data.h
+++ b/av1/common/common_data.h
@@ -518,6 +518,270 @@
 #endif  // CONFIG_EXT_PARTITION
 };
 
+#define USE_UV_RECT_TX 1
+static const TX_SIZE uv_txsize_lookup[BLOCK_SIZES][TX_SIZES_ALL][2][2] = {
+  //  ss_x == 0    ss_x == 0        ss_x == 1      ss_x == 1
+  //  ss_y == 0    ss_y == 1        ss_y == 0      ss_y == 1
+  {
+      // BLOCK_4X4
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_EXT_TX
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_4X8
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_EXT_TX
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_4X8, TX_4X4 }, { TX_4X4, TX_4X4 } },  // used
+#else
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },      // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_8X4
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_EXT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_8X4, TX_4X4 }, { TX_4X4, TX_4X4 } },  // used
+#else
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },      // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_8X8
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X4 }, { TX_4X8, TX_4X4 } },
+      { { TX_8X4, TX_8X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X4 }, { TX_4X8, TX_4X4 } },
+      { { TX_8X8, TX_8X4 }, { TX_4X8, TX_4X4 } },
+      { { TX_8X8, TX_8X4 }, { TX_4X8, TX_4X4 } },
+      { { TX_8X8, TX_8X4 }, { TX_4X8, TX_4X4 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_8X16
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_4X4, TX_4X4 } },
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_8X16, TX_8X8 }, { TX_4X8, TX_4X8 } },  // used
+#else
+      { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } },      // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_16X8
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_4X4 }, { TX_8X8, TX_4X4 } },
+      { { TX_8X8, TX_4X4 }, { TX_8X8, TX_8X8 } },
+      { { TX_8X8, TX_4X4 }, { TX_8X8, TX_8X8 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X4 }, { TX_4X8, TX_4X4 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_16X8, TX_8X4 }, { TX_8X8, TX_8X4 } },  // used
+#else
+      { { TX_8X8, TX_4X4 }, { TX_8X8, TX_4X4 } },      // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_16X16
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_8X8 }, { TX_8X8, TX_8X8 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X8 }, { TX_8X16, TX_8X8 } },
+      { { TX_16X8, TX_16X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X8 }, { TX_8X16, TX_8X8 } },
+      { { TX_16X16, TX_16X8 }, { TX_8X16, TX_8X8 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_16X32
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_8X8, TX_8X8 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_8X8, TX_8X8 } },
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_16X32, TX_16X16 }, { TX_8X16, TX_8X16 } },  // used
+#else
+      { { TX_16X16, TX_16X16 }, { TX_8X8, TX_8X8 } },  // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_32X16
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_8X8 }, { TX_16X16, TX_8X8 } },
+      { { TX_16X16, TX_8X8 }, { TX_16X16, TX_8X8 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X8 }, { TX_8X16, TX_8X8 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_INVALID, TX_INVALID }, { TX_INVALID, TX_INVALID } },
+#if CONFIG_RECT_TX && USE_UV_RECT_TX
+      { { TX_32X16, TX_16X8 }, { TX_16X16, TX_16X8 } },  // used
+#else
+      { { TX_16X16, TX_8X8 }, { TX_16X16, TX_8X8 } },  // used
+#endif  // CONFIG_RECT_TX && USE_UV_RECT_TX
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_32X32
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_16X16 }, { TX_16X16, TX_16X16 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X16 }, { TX_16X32, TX_16X16 } },
+      { { TX_32X16, TX_32X16 }, { TX_16X16, TX_16X16 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_32X64
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_32X32 }, { TX_16X16, TX_16X16 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X32 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X16, TX_32X16 }, { TX_16X16, TX_16X16 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_64X32
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_16X16 }, { TX_32X32, TX_16X16 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X16 }, { TX_16X32, TX_16X16 } },
+      { { TX_32X16, TX_16X16 }, { TX_32X16, TX_16X16 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_64X64
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_32X32 }, { TX_32X32, TX_32X32 } },
+#if CONFIG_EXT_PARTITION
+  },
+  {
+      // BLOCK_64X128
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_32X32 }, { TX_32X32, TX_32X32 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X32 }, { TX_16X32, TX_16X32 } },
+      { { TX_32X16, TX_32X16 }, { TX_32X16, TX_32X16 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_128X64
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_32X32 }, { TX_32X32, TX_32X32 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X32 }, { TX_16X32, TX_16X32 } },
+      { { TX_32X16, TX_32X16 }, { TX_32X16, TX_32X16 } },
+#endif  // CONFIG_EXT_TX
+  },
+  {
+      // BLOCK_128X128
+      { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } },
+      { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } },
+      { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } },
+      { { TX_32X32, TX_32X32 }, { TX_32X32, TX_32X32 } },
+#if CONFIG_EXT_TX
+      { { TX_4X8, TX_4X8 }, { TX_4X8, TX_4X8 } },
+      { { TX_8X4, TX_8X4 }, { TX_8X4, TX_8X4 } },
+      { { TX_8X16, TX_8X16 }, { TX_8X16, TX_8X16 } },
+      { { TX_16X8, TX_16X8 }, { TX_16X8, TX_16X8 } },
+      { { TX_16X32, TX_16X32 }, { TX_16X32, TX_16X32 } },
+      { { TX_32X16, TX_32X16 }, { TX_32X16, TX_32X16 } },
+#endif  // CONFIG_EXT_TX
+#endif  // CONFIG_EXT_PARTITION
+  },
+};
+
 // Generates 4 bit field in which each bit set to 1 represents
 // a blocksize partition  1111 means we split 64x64, 32x32, 16x16
 // and 8x8.  1000 means we just split the 64x64 to 32x32
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 9f1bbaa..b1ac2a0 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -137,6 +137,7 @@
 #define TX_16X16 ((TX_SIZE)2)  // 16x16 transform
 #define TX_32X32 ((TX_SIZE)3)  // 32x32 transform
 #define TX_SIZES ((TX_SIZE)4)
+#define TX_INVALID ((TX_SIZE)255)  // Invalid transform size
 
 #if CONFIG_EXT_TX
 #define TX_4X8 ((TX_SIZE)4)         // 4x8 transform
diff --git a/av1/common/loopfilter.c b/av1/common/loopfilter.c
index 726271e..7086be8 100644
--- a/av1/common/loopfilter.c
+++ b/av1/common/loopfilter.c
@@ -713,7 +713,7 @@
   // rectangular transfroms are used with the EXT_TX expt.
   const TX_SIZE tx_size_y = txsize_sqr_up_map[mbmi->tx_size];
   const TX_SIZE tx_size_uv =
-      get_uv_tx_size_impl(mbmi->tx_size, block_size, 1, 1);
+      txsize_sqr_up_map[uv_txsize_lookup[block_size][mbmi->tx_size][1][1]];
   const int filter_level = get_filter_level(lfi_n, mbmi);
   uint64_t *const left_y = &lfm->left_y[tx_size_y];
   uint64_t *const above_y = &lfm->above_y[tx_size_y];
@@ -1238,9 +1238,9 @@
       // Filter level can vary per MI
       if (!(lfl[r][c >> ss_x] = get_filter_level(&cm->lf_info, mbmi))) continue;
 
-      if (tx_size == TX_32X32)
+      if (txsize_sqr_up_map[tx_size] == TX_32X32)
         tx_size_mask = 3;
-      else if (tx_size == TX_16X16)
+      else if (txsize_sqr_up_map[tx_size] == TX_16X16)
         tx_size_mask = 1;
       else
         tx_size_mask = 0;
@@ -1249,8 +1249,8 @@
       if (is_inter_block(mbmi) && !mbmi->skip)
         tx_size =
             (plane->plane_type == PLANE_TYPE_UV)
-                ? get_uv_tx_size_impl(mbmi->inter_tx_size[blk_row][blk_col],
-                                      sb_type, ss_x, ss_y)
+                ? uv_txsize_lookup[sb_type][mbmi->inter_tx_size
+                                                [blk_row][blk_col]][ss_x][ss_y]
                 : mbmi->inter_tx_size[blk_row][blk_col];
 
 #if CONFIG_EXT_TX && CONFIG_RECT_TX
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2b6d1b5..13bb257 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -311,8 +311,7 @@
   const int tx_row = blk_row >> (1 - pd->subsampling_y);
   const int tx_col = blk_col >> (1 - pd->subsampling_x);
   const TX_SIZE plane_tx_size =
-      plane ? get_uv_tx_size_impl(mbmi->inter_tx_size[tx_row][tx_col], bsize, 0,
-                                  0)
+      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
             : mbmi->inter_tx_size[tx_row][tx_col];
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
@@ -381,13 +380,6 @@
 }
 #endif  // !CONFIG_VAR_TX || CONFIG_SUPER_TX
 
-static INLINE TX_SIZE dec_get_uv_tx_size(const MB_MODE_INFO *mbmi, int n4_wl,
-                                         int n4_hl) {
-  // get minimum log2 num4x4s dimension
-  const int x = AOMMIN(n4_wl, n4_hl);
-  return AOMMIN(txsize_sqr_map[mbmi->tx_size], x);
-}
-
 static INLINE void dec_reset_skip_context(MACROBLOCKD *xd) {
   int i;
   for (i = 0; i < MAX_MB_PLANE; i++) {
@@ -1225,9 +1217,7 @@
     }
     for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
       const struct macroblockd_plane *const pd = &xd->plane[plane];
-      const TX_SIZE tx_size =
-          plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
-                : mbmi->tx_size;
+      const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
       const int num_4x4_w = pd->n4_w;
       const int num_4x4_h = pd->n4_h;
       const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
@@ -1319,8 +1309,7 @@
         int block = 0;
 #if CONFIG_EXT_TX && CONFIG_RECT_TX
         const TX_SIZE tx_size =
-            plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
-                  : mbmi->tx_size;
+            plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
 
         if (tx_size >= TX_SIZES) {  // rect txsize is used
           const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
@@ -1352,8 +1341,7 @@
 #endif
 #else
         const TX_SIZE tx_size =
-            plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
-                  : mbmi->tx_size;
+            plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
         const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
         const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
         const int max_blocks_wide =
@@ -1730,8 +1718,7 @@
         const int num_4x4_w = pd->n4_w;
         const int num_4x4_h = pd->n4_h;
         int row, col;
-        const TX_SIZE tx_size =
-            i ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl) : mbmi->tx_size;
+        const TX_SIZE tx_size = i ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
         const int stepr = num_4x4_blocks_high_txsize_lookup[tx_size];
         const int stepc = num_4x4_blocks_wide_txsize_lookup[tx_size];
         const int max_blocks_wide =
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 07ea72d..a5b5396 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -796,9 +796,9 @@
 
   if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
 
-  plane_tx_size = plane ? get_uv_tx_size_impl(
-                              mbmi->inter_tx_size[tx_row][tx_col], bsize, 0, 0)
-                        : mbmi->inter_tx_size[tx_row][tx_col];
+  plane_tx_size =
+      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
+            : mbmi->inter_tx_size[tx_row][tx_col];
 
   if (tx_size == plane_tx_size) {
     pack_mb_tokens(w, tp, tok_end, bit_depth, tx_size);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index bc17618..b5d4712 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -5087,7 +5087,8 @@
             mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;
     }
     ++td->counts->tx_size_totals[txsize_sqr_map[mbmi->tx_size]];
-    ++td->counts->tx_size_totals[get_uv_tx_size(mbmi, &xd->plane[1])];
+    ++td->counts
+          ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
 #if CONFIG_EXT_TX
     if (get_ext_tx_types(mbmi->tx_size, bsize, is_inter_block(mbmi)) > 1 &&
         cm->base_qindex > 0 && !mbmi->skip &&
@@ -5987,8 +5988,8 @@
     pnskip = 1;
 
     tx_size = max_txsize_lookup[bsize];
-    tx_size = get_uv_tx_size_impl(tx_size, bsize, cm->subsampling_x,
-                                  cm->subsampling_y);
+    tx_size =
+        uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
     av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
     coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
 
@@ -5998,8 +5999,8 @@
                       &this_dist, &pnsse, &pnskip);
 #else
     tx_size = max_txsize_lookup[bsize];
-    tx_size = get_uv_tx_size_impl(tx_size, bsize, cm->subsampling_x,
-                                  cm->subsampling_y);
+    tx_size =
+        uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
     av1_subtract_plane(x, bsize, plane);
     av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
                                  &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index 93ffdaa..5a21ebd 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -871,9 +871,9 @@
 
   if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
 
-  plane_tx_size = plane ? get_uv_tx_size_impl(
-                              mbmi->inter_tx_size[tx_row][tx_col], bsize, 0, 0)
-                        : mbmi->inter_tx_size[tx_row][tx_col];
+  plane_tx_size =
+      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
+            : mbmi->inter_tx_size[tx_row][tx_col];
 
   if (tx_size == plane_tx_size) {
     encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 9a15183..63cc75e 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -3347,9 +3347,9 @@
 
   if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
 
-  plane_tx_size = plane ? get_uv_tx_size_impl(
-                              mbmi->inter_tx_size[tx_row][tx_col], bsize, 0, 0)
-                        : mbmi->inter_tx_size[tx_row][tx_col];
+  plane_tx_size =
+      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
+            : mbmi->inter_tx_size[tx_row][tx_col];
 
   if (tx_size == plane_tx_size) {
     int coeff_ctx, i;
@@ -7750,8 +7750,8 @@
       return;
     }
   }
-  max_uv_tx_size = get_uv_tx_size_impl(
-      xd->mi[0]->mbmi.tx_size, bsize, pd[1].subsampling_x, pd[1].subsampling_y);
+  max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
+                                   [pd[1].subsampling_x][pd[1].subsampling_y];
   rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
                           &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
 
@@ -7971,8 +7971,8 @@
     return;
   if (rate_y == INT_MAX) return;
 
-  uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, xd->plane[1].subsampling_x,
-                              xd->plane[1].subsampling_y);
+  uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
+                          [xd->plane[1].subsampling_y];
   if (rate_uv_intra[uv_tx] == INT_MAX) {
     choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
                          &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
@@ -8673,8 +8673,8 @@
       if (mbmi->mode == DC_PRED) dc_skipped = 0;
 #endif  // CONFIG_EXT_INTRA
 
-      uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
-                                  pd->subsampling_y);
+      uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
+                              [pd->subsampling_y];
       if (rate_uv_intra[uv_tx] == INT_MAX) {
         choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
                              &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
@@ -9334,9 +9334,8 @@
     super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize,
                     best_rd);
     if (rate_y == INT_MAX) goto PALETTE_EXIT;
-    uv_tx =
-        get_uv_tx_size_impl(mbmi->tx_size, bsize, xd->plane[1].subsampling_x,
-                            xd->plane[1].subsampling_y);
+    uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
+                            [xd->plane[1].subsampling_y];
     if (rate_uv_intra[uv_tx] == INT_MAX) {
       choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
                            &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index d76c1a5..b86baa8 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -584,9 +584,9 @@
 
   if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
 
-  plane_tx_size = plane ? get_uv_tx_size_impl(
-                              mbmi->inter_tx_size[tx_row][tx_col], bsize, 0, 0)
-                        : mbmi->inter_tx_size[tx_row][tx_col];
+  plane_tx_size =
+      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
+            : mbmi->inter_tx_size[tx_row][tx_col];
 
   if (tx_size == plane_tx_size) {
     const struct macroblockd_plane *const pd = &xd->plane[plane];