[lv_map_multi] Simplified multisymbol BR coding

Multisymbol BR coding is simplified as follows.
1. Remove computation of level counts by using a template of size 8;
2. Context is derived by using a template of size 3.
3. lps and eob probabilities are trained.
4. Share contexts between TX_16X16 and above.

The number of probability values used in BR coding are reduced from 1152 to 378.

Change-Id: I0419127e871f9e566c2489aa4b1825c5364aec5a
diff --git a/av1/common/entropy.h b/av1/common/entropy.h
index 3b3e3e5..2e359e7 100644
--- a/av1/common/entropy.h
+++ b/av1/common/entropy.h
@@ -68,6 +68,7 @@
 #define SIG_COEF_CONTEXTS_2D 26
 #define SIG_COEF_CONTEXTS_1D 16
 #if CONFIG_LV_MAP_MULTI
+#define USE_CAUSAL_BR_CTX 1
 #define USE_BASE_EOB_ALPHABET 1
 #define SIG_COEF_CONTEXTS_EOB 4
 #define SIG_COEF_CONTEXTS \
@@ -95,7 +96,11 @@
 
 #define BR_TMP_OFFSET 12
 #define BR_REF_CAT 4
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+#define LEVEL_CONTEXTS 21
+#else
 #define LEVEL_CONTEXTS (BR_TMP_OFFSET * BR_REF_CAT)
+#endif
 
 #define NUM_BASE_LEVELS 2
 
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index ca85aa0..db6f282 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -436,76 +436,123 @@
 
 static const aom_prob
     default_eob_flag[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS] = {
-      { { 225, 240, 225, 200, 128, 128, 128, 128, 128, 128, 128,
-          245, 246, 238, 203, 128, 128, 128, 128, 128, 128, 128 },
-        { 181, 219, 192, 144, 128, 128, 128, 128, 128, 128, 128,
-          218, 231, 199, 152, 128, 128, 128, 128, 128, 128, 128 } },
-      { { 233, 247, 240, 234, 211, 194, 128, 128, 128, 128, 128,
-          252, 252, 249, 242, 221, 208, 128, 128, 128, 128, 128 },
-        { 154, 222, 204, 180, 132, 128, 128, 128, 128, 128, 128,
-          216, 235, 206, 181, 121, 112, 128, 128, 128, 128, 128 } },
-      { { 233, 246, 241, 238, 231, 216, 186, 171, 128, 128, 128,
-          251, 252, 251, 244, 233, 218, 192, 191, 128, 128, 128 },
-        { 117, 221, 214, 223, 215, 202, 176, 116, 128, 128, 128,
-          205, 234, 219, 183, 195, 126, 76,  128, 128, 128, 128 } },
-      { { 194, 231, 213, 215, 207, 200, 183, 169, 135, 168, 128,
-          240, 246, 243, 238, 210, 201, 172, 133, 107, 128, 128 },
-        { 122, 232, 230, 244, 250, 247, 252, 253, 254, 52,  128,
+      { { 177, 226, 194, 146, 128, 128, 128, 128, 128, 128, 128,
+          231, 239, 225, 162, 128, 128, 128, 128, 128, 128, 128 },
+        { 123, 211, 166, 117, 128, 128, 128, 128, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 197, 242, 229, 219, 187, 151, 128, 128, 128, 128, 128,
+          236, 246, 239, 230, 203, 141, 128, 128, 128, 128, 128 },
+        { 124, 225, 204, 179, 116, 98,  128, 128, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 210, 244, 236, 229, 217, 201, 177, 154, 128, 128, 128,
+          251, 252, 247, 215, 201, 194, 164, 128, 128, 128, 128 },
+        { 86,  222, 202, 192, 172, 154, 132, 109, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 204, 242, 224, 223, 213, 202, 187, 176, 152, 132, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 72,  227, 200, 212, 190, 150, 136, 173, 183, 82,  128,
           128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
 #if CONFIG_TX64X64
-      { { 194, 231, 213, 215, 207, 200, 183, 169, 135, 168, 128,
-          240, 246, 243, 238, 210, 201, 172, 133, 107, 128, 128 },
-        { 122, 232, 230, 244, 250, 247, 252, 253, 254, 52,  128,
-          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 204, 242, 224, 223, 213, 202, 187, 176, 152, 132, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 72,  227, 200, 212, 190, 150, 136, 173, 183, 82,  128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } }
 #endif
     };
 
 static const aom_prob
     default_eob_extra[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS] = {
-      { {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        },
-        {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        } },
-      { {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        },
-        {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        } },
-      { {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        },
-        {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        } },
-      { {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        },
-        {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        } },
+      { { 128, 128, 128, 138, 138, 148, 128, 128, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 128, 128, 128, 156, 156, 152, 128, 128, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 128, 128, 128, 134, 148, 143, 144, 140, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 128, 128, 128, 165, 164, 160, 161, 157, 128, 128, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 128, 128, 128, 142, 145, 146, 153, 144, 139, 136, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 128, 128, 128, 175, 168, 162, 162, 156, 157, 163, 128,
+          128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+      { { 128, 128, 128, 180, 161, 149, 151, 158, 153, 142, 141,
+          141, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 128, 128, 128, 204, 172, 156, 139, 170, 170, 154, 166,
+          157, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
 #if CONFIG_TX64X64
-      { {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        },
-        {
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-            145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
-        } },
+      { { 128, 128, 128, 177, 160, 150, 147, 157, 151, 142, 139,
+          133, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+        { 128, 128, 128, 200, 173, 159, 135, 158, 174, 160, 172,
+          163, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } }
 #endif
     };
 
+#if CONFIG_LV_MAP_MULTI
+const aom_prob default_coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE -
+                                                        1][LEVEL_CONTEXTS] = {
+  { { { 87,  128, 170, 197, 212, 221, 233, 73,  90,  128, 162,
+        184, 196, 212, 64,  81,  115, 149, 173, 183, 207 },
+      { 105, 132, 168, 194, 208, 219, 232, 93,  100, 129, 159,
+        178, 193, 210, 78,  94,  118, 146, 165, 182, 197 },
+      { 118, 136, 167, 190, 206, 216, 231, 112, 111, 130, 155,
+        175, 188, 207, 103, 104, 122, 144, 163, 176, 195 } },
+    { { 69,  108, 160, 197, 216, 222, 233, 50,  71,  119, 154,
+        181, 196, 207, 35,  58,  98,  135, 158, 184, 182 },
+      { 91,  120, 163, 197, 211, 222, 232, 67,  82,  124, 157,
+        177, 189, 204, 57,  77,  104, 134, 154, 181, 219 },
+      { 112, 130, 166, 194, 212, 219, 231, 97,  100, 128, 153,
+        181, 186, 199, 96,  90,  109, 119, 161, 148, 174 } } },
+  { { { 101, 145, 185, 207, 218, 226, 237, 112, 112, 142, 170,
+        188, 200, 218, 63,  83,  116, 148, 170, 184, 205 },
+      { 119, 149, 184, 205, 216, 224, 236, 139, 123, 144, 168,
+        185, 197, 217, 83,  95,  119, 147, 166, 181, 204 },
+      { 133, 154, 182, 202, 214, 222, 236, 155, 134, 148, 168,
+        184, 195, 215, 97,  105, 124, 147, 164, 178, 201 } },
+    { { 93,  125, 164, 191, 206, 216, 236, 70,  81,  116, 153,
+        175, 193, 216, 39,  62,  100, 138, 162, 182, 207 },
+      { 105, 130, 162, 188, 202, 216, 232, 85,  92,  118, 149,
+        175, 191, 214, 55,  74,  103, 145, 163, 177, 205 },
+      { 115, 136, 161, 185, 202, 213, 233, 99,  105, 128, 148,
+        168, 180, 209, 79,  83,  113, 140, 165, 175, 191 } } },
+  { { { 111, 151, 188, 209, 220, 227, 241, 145, 145, 165, 186,
+        201, 210, 228, 73,  93,  123, 153, 174, 188, 211 },
+      { 134, 155, 188, 208, 219, 226, 241, 173, 165, 171, 187,
+        200, 209, 227, 95,  108, 130, 154, 173, 187, 210 },
+      { 154, 162, 189, 207, 217, 225, 240, 188, 181, 178, 188,
+        199, 208, 227, 112, 121, 137, 157, 173, 186, 209 } },
+    { { 126, 155, 188, 208, 218, 220, 243, 142, 142, 157, 168,
+        189, 201, 224, 53,  65,  97,  117, 145, 169, 186 },
+      { 144, 163, 188, 206, 217, 224, 239, 173, 165, 172, 175,
+        187, 211, 224, 88,  85,  97,  124, 145, 169, 194 },
+      { 158, 170, 188, 203, 212, 220, 238, 179, 182, 183, 182,
+        193, 200, 226, 100, 108, 111, 128, 140, 163, 206 } } },
+  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } },
+#if CONFIG_TX64X64
+  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } },
+    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+        128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }
+#endif
+};
+#else
 const aom_prob default_coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS] = {
   { { 115, 128, 87,  119, 128, 128, 128, 128, 62,  94,  125, 128,
       151, 164, 113, 140, 147, 128, 128, 128, 80,  111, 137, 142,
@@ -550,6 +597,7 @@
       185, 187, 146, 181, 185, 128, 128, 128, 101, 129, 157, 170 } }
 #endif
 };
+#endif
 
 #if !CONFIG_LV_MAP_MULTI
 const aom_prob
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index bf738c8..45d44ca 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -158,9 +158,11 @@
   aom_prob dc_sign[PLANE_TYPES][DC_SIGN_CONTEXTS];
   aom_prob coeff_base[TX_SIZES][PLANE_TYPES][NUM_BASE_LEVELS]
                      [COEFF_BASE_CONTEXTS];
-  aom_prob coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS];
 #if !CONFIG_LV_MAP_MULTI
+  aom_prob coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS];
   aom_prob coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS][LEVEL_CONTEXTS];
+#else
+  aom_prob coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE - 1][LEVEL_CONTEXTS];
 #endif
 
   aom_cdf_prob txb_skip_cdf[TX_SIZES][TXB_SKIP_CONTEXTS][CDF_SIZE(2)];
@@ -338,10 +340,13 @@
   unsigned int dc_sign[PLANE_TYPES][DC_SIGN_CONTEXTS][2];
   unsigned int coeff_base[TX_SIZES][PLANE_TYPES][NUM_BASE_LEVELS]
                          [COEFF_BASE_CONTEXTS][2];
-  unsigned int coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS][2];
 #if !CONFIG_LV_MAP_MULTI
   unsigned int coeff_br[TX_SIZES][PLANE_TYPES][BASE_RANGE_SETS][LEVEL_CONTEXTS]
                        [2];
+  unsigned int coeff_lps[TX_SIZES][PLANE_TYPES][LEVEL_CONTEXTS][2];
+#else
+  unsigned int coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE - 1][LEVEL_CONTEXTS]
+                        [2];
 #endif
 #endif  // CONFIG_LV_MAP
 
diff --git a/av1/common/txb_common.c b/av1/common/txb_common.c
index 44327a5..f0ef25b 100644
--- a/av1/common/txb_common.c
+++ b/av1/common/txb_common.c
@@ -195,15 +195,17 @@
     for (plane = 0; plane < PLANE_TYPES; ++plane) {
 #if CONFIG_LV_MAP_MULTI
       for (ctx = 0; ctx < LEVEL_CONTEXTS; ++ctx) {
-        int p = 32768 - fc->coeff_lps[tx_size][plane][ctx] * 128;
+        int p = 32768 - fc->coeff_lps[tx_size][plane][0][ctx] * 128;
         int sum = p;
         fc->coeff_br_cdf[tx_size][plane][ctx][0] = AOM_ICDF(sum);
+        p = 32768 - fc->coeff_lps[tx_size][plane][1][ctx] * 128;
         sum += ((32768 - sum) * p) >> 15;
         fc->coeff_br_cdf[tx_size][plane][ctx][1] = AOM_ICDF(sum);
+        p = 32768 - fc->coeff_lps[tx_size][plane][2][ctx] * 128;
         sum += ((32768 - sum) * p) >> 15;
         fc->coeff_br_cdf[tx_size][plane][ctx][2] = AOM_ICDF(sum);
         fc->coeff_br_cdf[tx_size][plane][ctx][3] = AOM_ICDF(32768);
-        fc->coeff_br_cdf[tx_size][plane][ctx][4] = AOM_ICDF(32768);
+        fc->coeff_br_cdf[tx_size][plane][ctx][4] = 0;
         // printf("br_cdf: %d %d %2d : %3d %3d %3d\n", tx_size, plane, ctx,
         //        fc->coeff_br_cdf[tx_size][plane][ctx][0] >> 7,
         //        fc->coeff_br_cdf[tx_size][plane][ctx][1] >> 7,
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h
index f83c907..2d94ae5 100644
--- a/av1/common/txb_common.h
+++ b/av1/common/txb_common.h
@@ -43,10 +43,29 @@
 };
 
 #define CONTEXT_MAG_POSITION_NUM 3
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+static const int mag_ref_offset_with_txclass[3][CONTEXT_MAG_POSITION_NUM][2] = {
+  { { 0, 1 }, { 1, 0 }, { 1, 1 } },
+  { { 0, 1 }, { 1, 0 }, { 0, 2 } },
+  { { 0, 1 }, { 1, 0 }, { 2, 0 } }
+};
+#endif
 static const int mag_ref_offset[CONTEXT_MAG_POSITION_NUM][2] = {
   { 0, 1 }, { 1, 0 }, { 1, 1 }
 };
 
+static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
+  switch (tx_type) {
+    case V_DCT:
+    case V_ADST:
+    case V_FLIPADST: return TX_CLASS_VERT;
+    case H_DCT:
+    case H_ADST:
+    case H_FLIPADST: return TX_CLASS_HORIZ;
+    default: return TX_CLASS_2D;
+  }
+}
+
 static INLINE void get_base_count_mag(int *mag, int *count,
                                       const tran_low_t *tcoeffs, int bwl,
                                       int height, int row, int col) {
@@ -99,6 +118,20 @@
   return count;
 }
 
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+static INLINE void get_level_mag_with_txclass(const uint8_t *const levels,
+                                              const int stride, const int row,
+                                              const int col, int *const mag,
+                                              const TX_CLASS tx_class) {
+  for (int idx = 0; idx < CONTEXT_MAG_POSITION_NUM; ++idx) {
+    const int ref_row = row + mag_ref_offset_with_txclass[tx_class][idx][0];
+    const int ref_col = col + mag_ref_offset_with_txclass[tx_class][idx][1];
+    const int pos = ref_row * stride + ref_col;
+    mag[idx] = levels[pos];
+  }
+}
+#endif
+
 static INLINE void get_level_mag(const uint8_t *const levels, const int stride,
                                  const int row, const int col, int *const mag) {
   for (int idx = 0; idx < CONTEXT_MAG_POSITION_NUM; ++idx) {
@@ -267,16 +300,45 @@
 
 static INLINE int get_br_ctx(const uint8_t *const levels,
                              const int c,  // raster order
-                             const int bwl, const int count) {
+                             const int bwl, const int count
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+                             ,
+                             const TX_TYPE tx_type
+#endif
+                             ) {
   const int row = c >> bwl;
   const int col = c - (row << bwl);
   const int stride = (1 << bwl) + TX_PAD_HOR;
   int mag = 0;
   int nb_mag[3] = { 0 };
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+  (void)count;
+  const TX_CLASS tx_class = get_tx_class(tx_type);
+  get_level_mag_with_txclass(levels, stride, row, col, nb_mag, tx_class);
+
+  mag = AOMMIN(nb_mag[0], COEFF_BASE_RANGE + NUM_BASE_LEVELS + 1) +
+        AOMMIN(nb_mag[1], COEFF_BASE_RANGE + NUM_BASE_LEVELS + 1) +
+        AOMMIN(nb_mag[2], COEFF_BASE_RANGE + NUM_BASE_LEVELS + 1);
+  mag = AOMMIN((mag + 1) >> 1, 6);
+  if (c == 0) return mag;
+  if (tx_class == 0) {
+    if ((row < 2) && (col < 2)) return mag + 7;
+  } else {
+    if (tx_class == 1) {
+      if (col == 0) return mag + 7;
+    } else {
+      if (tx_class == 2) {
+        if (row == 0) return mag + 7;
+      }
+    }
+  }
+  return mag + 14;
+#else
   get_level_mag(levels, stride, row, col, nb_mag);
   for (int idx = 0; idx < 3; ++idx) mag = AOMMAX(mag, nb_mag[idx]);
   const int ctx = get_br_ctx_from_count_mag(row, col, count, mag);
   return ctx;
+#endif
 }
 
 #define SIG_REF_OFFSET_NUM 5
@@ -347,18 +409,6 @@
   return count;
 }
 
-static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
-  switch (tx_type) {
-    case V_DCT:
-    case V_ADST:
-    case V_FLIPADST: return TX_CLASS_VERT;
-    case H_DCT:
-    case H_ADST:
-    case H_FLIPADST: return TX_CLASS_HORIZ;
-    default: return TX_CLASS_2D;
-  }
-}
-
 // TODO(angiebird): optimize this function by generate a table that maps from
 // count to ctx
 static INLINE int get_nz_map_ctx_from_count(int count,
diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c
index 06324a0..3f19372 100644
--- a/av1/decoder/decodetxb.c
+++ b/av1/decoder/decodetxb.c
@@ -317,7 +317,9 @@
   }
 
   if (num_updates) {
+#if !CONFIG_LV_MAP_MULTI
     av1_get_br_level_counts(levels, width, height, level_counts);
+#endif
     for (c = 0; c < num_updates; ++c) {
       const int pos = update_pos[c];
       uint8_t *const level = &levels[get_paded_idx(pos, bwl)];
@@ -330,17 +332,26 @@
       if (*level <= NUM_BASE_LEVELS) continue;
 #endif
 
+#if !CONFIG_LV_MAP_MULTI
       ctx = get_br_ctx(levels, pos, bwl, level_counts[pos]);
+#endif
 
 #if CONFIG_LV_MAP_MULTI
+#if USE_CAUSAL_BR_CTX
+      ctx = get_br_ctx(levels, pos, bwl, level_counts[pos], tx_type);
+#else
+      ctx = get_br_ctx(levels, pos, bwl, level_counts[pos]);
+#endif
       for (idx = 0; idx < COEFF_BASE_RANGE / (BR_CDF_SIZE - 1); ++idx) {
         int k = av1_read_record_symbol(
-            counts, r, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][ctx],
+            counts, r,
+            ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_16X16)][plane_type][ctx],
             BR_CDF_SIZE, ACCT_STR);
         *level += k;
         if (counts) {
-          for (int lps = 0; lps < BR_CDF_SIZE; lps++) {
-            ++counts->coeff_lps[txs_ctx][plane_type][ctx][lps == k];
+          for (int lps = 0; lps < BR_CDF_SIZE - 1; lps++) {
+            ++counts->coeff_lps[AOMMIN(txs_ctx, TX_16X16)][plane_type][lps][ctx]
+                               [lps == k];
             if (lps == k) break;
           }
         }
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 253db3c..50a5a99 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -487,7 +487,9 @@
   }
 
   if (update_eob >= 0) {
+#if !CONFIG_LV_MAP_MULTI
     av1_get_br_level_counts(levels, width, height, level_counts);
+#endif
     for (c = update_eob; c >= 0; --c) {
       const tran_low_t level = abs(tcoeff[scan[c]]);
       int idx;
@@ -495,15 +497,24 @@
 
       if (level <= NUM_BASE_LEVELS) continue;
 
-      // level is above 1.
+// level is above 1.
+#if !CONFIG_LV_MAP_MULTI
       ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]);
-
+#endif
       int base_range = level - 1 - NUM_BASE_LEVELS;
 #if CONFIG_LV_MAP_MULTI
+#if USE_CAUSAL_BR_CTX
+      ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]], tx_type);
+
+#else
+      ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]);
+#endif
       for (idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
         int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
-        aom_write_symbol(w, k, ec_ctx->coeff_br_cdf[txs_ctx][plane_type][ctx],
-                         BR_CDF_SIZE);
+        aom_write_symbol(
+            w, k,
+            ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_16X16)][plane_type][ctx],
+            BR_CDF_SIZE);
         if (k < BR_CDF_SIZE - 1) break;
       }
       if (base_range < COEFF_BASE_RANGE) continue;
@@ -690,8 +701,9 @@
 
   const int seg_eob = av1_get_max_eob(tx_size);
   int eob_cost = get_eob_cost(eob, seg_eob, coeff_costs, tx_type);
-
+#if !CONFIG_LV_MAP_MULTI
   av1_get_br_level_counts(levels, width, height, level_counts);
+#endif
   cost += eob_cost;
 #if USE_CAUSAL_BASE_CTX
   int coeff_ctx = 0;
@@ -767,7 +779,11 @@
 #endif  // CONFIG_LV_MAP_MULTI
       if (level > NUM_BASE_LEVELS) {
         int ctx;
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+        ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]], tx_type);
+#else
         ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]);
+#endif
         int base_range = level - 1 - NUM_BASE_LEVELS;
         if (base_range < COEFF_BASE_RANGE) {
           cost += coeff_costs->lps_cost[ctx][base_range];
@@ -1612,11 +1628,19 @@
     if (abs_qc > NUM_BASE_LEVELS) {
       const int row = scan[scan_idx] >> txb_info->bwl;
       const int col = scan[scan_idx] - (row << txb_info->bwl);
+
+#if CONFIG_LV_MAP_MULTI && USE_CAUSAL_BR_CTX
+      (void)col;
+      const int count = 0;
+      const int ctx = get_br_ctx(txb_info->levels, scan[scan_idx],
+                                 txb_info->bwl, count, txb_info->tx_type);
+#else
       const int count = get_level_count(
           txb_info->levels, (1 << txb_info->bwl) + TX_PAD_HOR, row, col,
           NUM_BASE_LEVELS, br_ref_offset, BR_CONTEXT_POSITION_NUM);
       const int ctx =
           get_br_ctx(txb_info->levels, scan[scan_idx], txb_info->bwl, count);
+#endif
       cost += get_br_cost(abs_qc, ctx, txb_costs->lps_cost[ctx]);
       cost += get_golomb_cost(abs_qc);
     }
@@ -2352,7 +2376,9 @@
   }
 
   if (update_eob >= 0) {
+#if !CONFIG_LV_MAP_MULTI
     av1_get_br_level_counts(levels, width, height, level_counts);
+#endif
     for (c = update_eob; c >= 0; --c) {
       const tran_low_t level = abs(tcoeff[scan[c]]);
       int idx;
@@ -2360,19 +2386,28 @@
 
       if (level <= NUM_BASE_LEVELS) continue;
 
-      // level is above 1.
+// level is above 1.
+#if !CONFIG_LV_MAP_MULTI
       ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]);
+#endif
 
       int base_range = level - 1 - NUM_BASE_LEVELS;
 #if CONFIG_LV_MAP_MULTI
+#if USE_CAUSAL_BR_CTX
+      ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]], tx_type);
+#else
+      ctx = get_br_ctx(levels, scan[c], bwl, level_counts[scan[c]]);
+#endif
       for (idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
         int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
         // printf("br_update: %d %d %2d : %2d %d\n", txsize_ctx, plane, ctx,
         // base_range, k);
-        update_cdf(ec_ctx->coeff_br_cdf[txsize_ctx][plane_type][ctx], k,
-                   BR_CDF_SIZE);
-        for (int lps = 0; lps < BR_CDF_SIZE; lps++) {
-          ++td->counts->coeff_lps[txsize_ctx][plane_type][ctx][lps == k];
+        update_cdf(
+            ec_ctx->coeff_br_cdf[AOMMIN(txsize_ctx, TX_16X16)][plane_type][ctx],
+            k, BR_CDF_SIZE);
+        for (int lps = 0; lps < BR_CDF_SIZE - 1; lps++) {
+          ++td->counts->coeff_lps[AOMMIN(txsize_ctx, TX_16X16)][plane_type][lps]
+                                 [ctx][lps == k];
           if (lps == k) break;
         }
 
diff --git a/tools/aom_entropy_optimizer.c b/tools/aom_entropy_optimizer.c
index f0ac260..4748490 100644
--- a/tools/aom_entropy_optimizer.c
+++ b/tools/aom_entropy_optimizer.c
@@ -676,6 +676,27 @@
 
   cts_each_dim[0] = TX_SIZES;
   cts_each_dim[1] = PLANE_TYPES;
+  cts_each_dim[2] = EOB_COEF_CONTEXTS;
+  cts_each_dim[3] = 2;
+  optimize_entropy_table(
+      &fc.eob_extra[0][0][0][0], probsfile, 4, cts_each_dim, NULL, 1,
+      "static const aom_prob "
+      "default_eob_extra[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS]");
+
+#if CONFIG_LV_MAP_MULTI
+  cts_each_dim[0] = TX_SIZES;
+  cts_each_dim[1] = PLANE_TYPES;
+  cts_each_dim[2] = BR_CDF_SIZE - 1;
+  cts_each_dim[3] = LEVEL_CONTEXTS;
+  cts_each_dim[4] = 2;
+  optimize_entropy_table(&fc.coeff_lps[0][0][0][0][0], probsfile, 5,
+                         cts_each_dim, NULL, 1,
+                         "static const aom_prob "
+                         "default_coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE-"
+                         "1][LEVEL_CONTEXTS]");
+#else
+  cts_each_dim[0] = TX_SIZES;
+  cts_each_dim[1] = PLANE_TYPES;
   cts_each_dim[2] = LEVEL_CONTEXTS;
   cts_each_dim[3] = 2;
   optimize_entropy_table(
@@ -686,7 +707,7 @@
                      "static const aom_cdf_prob "
                      "default_coeff_lps_cdf[TX_SIZES][PLANE_TYPES][LEVEL_"
                      "CONTEXTS][CDF_SIZE(2)]");
-#if !CONFIG_LV_MAP_MULTI
+
   cts_each_dim[0] = TX_SIZES;
   cts_each_dim[1] = PLANE_TYPES;
   cts_each_dim[2] = BASE_RANGE_SETS;