Use table lookup for computing base ctx

This will speed up lv_map by 4.3%

Change-Id: I886f67b9f1ae2e5f567e114fa34cf3ba437b8381
diff --git a/av1/common/entropy.h b/av1/common/entropy.h
index cdec99c..49ed92e 100644
--- a/av1/common/entropy.h
+++ b/av1/common/entropy.h
@@ -74,6 +74,8 @@
 
 #define COEFF_CONTEXT_BITS 6
 #define COEFF_CONTEXT_MASK ((1 << COEFF_CONTEXT_BITS) - 1)
+
+#define BASE_CONTEXT_POSITION_NUM 12
 #endif
 
 DECLARE_ALIGNED(16, extern const uint8_t, av1_pt_energy_class[ENTROPY_TOKENS]);
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 9c5e164..65d165e 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -15,6 +15,9 @@
 #include "av1/common/scan.h"
 #include "av1/common/onyxc_int.h"
 #include "av1/common/seg_common.h"
+#if CONFIG_LV_MAP
+#include "av1/common/txb_common.h"
+#endif
 
 #if CONFIG_LV_MAP
 const aom_prob default_txb_skip[TX_SIZES][TXB_SKIP_CONTEXTS] = {
@@ -5130,6 +5133,9 @@
   av1_default_coef_probs(cm);
   init_mode_probs(cm->fc);
   av1_init_mv_probs(cm);
+#if CONFIG_LV_MAP
+  av1_init_lv_map(cm);
+#endif
 #if CONFIG_PVQ
   av1_default_pvq_probs(cm);
 #endif  // CONFIG_PVQ
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index c12db9d..c4df1b8 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -170,6 +170,15 @@
   InternalFrameBufferList int_frame_buffers;
 } BufferPool;
 
+#if CONFIG_LV_MAP
+typedef struct {
+  int base_ctx_table[2 /*row*/][2 /*col*/][2 /*sig_map*/]
+                    [BASE_CONTEXT_POSITION_NUM + 1];
+} LV_MAP_CTX_TABLE;
+typedef int BASE_CTX_TABLE[2 /*col*/][2 /*sig_map*/]
+                          [BASE_CONTEXT_POSITION_NUM + 1];
+#endif
+
 typedef struct AV1Common {
   struct aom_internal_error_info error;
   aom_color_space_t color_space;
@@ -460,6 +469,9 @@
 #if CONFIG_NCOBMC_ADAPT_WEIGHT
   NCOBMC_KERNELS ncobmc_kernels[ADAPT_OVERLAP_BLOCKS][ALL_NCOBMC_MODES];
 #endif
+#if CONFIG_LV_MAP
+  LV_MAP_CTX_TABLE coeff_ctx_table;
+#endif
 } AV1_COMMON;
 
 #if CONFIG_REFERENCE_BUFFER
diff --git a/av1/common/txb_common.c b/av1/common/txb_common.c
index eb66ba1..88fcf6c 100644
--- a/av1/common/txb_common.c
+++ b/av1/common/txb_common.c
@@ -10,6 +10,9 @@
  */
 #include "aom/aom_integer.h"
 #include "av1/common/onyxc_int.h"
+#if CONFIG_LV_MAP
+#include "av1/common/txb_common.h"
+#endif
 
 const int16_t av1_coeff_band_4x4[16] = { 0, 1, 2,  3,  4,  5,  6,  7,
                                          8, 9, 10, 11, 12, 13, 14, 15 };
@@ -148,3 +151,17 @@
             counts->coeff_lps[tx_size][plane][ctx], count_sat, update_factor);
   }
 }
+
+void av1_init_lv_map(AV1_COMMON *cm) {
+  LV_MAP_CTX_TABLE *coeff_ctx_table = &cm->coeff_ctx_table;
+  for (int row = 0; row < 2; ++row) {
+    for (int col = 0; col < 2; ++col) {
+      for (int sig_mag = 0; sig_mag < 2; ++sig_mag) {
+        for (int count = 0; count < BASE_CONTEXT_POSITION_NUM + 1; ++count) {
+          coeff_ctx_table->base_ctx_table[row][col][sig_mag][count] =
+              get_base_ctx_from_count_mag(row, col, count, sig_mag);
+        }
+      }
+    }
+  }
+}
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h
index 6dde2a0..b19d50d 100644
--- a/av1/common/txb_common.h
+++ b/av1/common/txb_common.h
@@ -28,7 +28,6 @@
   return txsize_sqr_up_map[tx_size];
 }
 
-#define BASE_CONTEXT_POSITION_NUM 12
 static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
   /* clang-format off*/
   { -2, 0 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -2 }, { 0, -1 }, { 0, 1 },
@@ -129,9 +128,8 @@
 }
 
 static INLINE int get_base_ctx_from_count_mag(int row, int col, int count,
-                                              int mag, int level) {
+                                              int sig_mag) {
   const int ctx = (count + 1) >> 1;
-  const int sig_mag = mag > level;
   int ctx_idx = -1;
   if (row == 0 && col == 0) {
     ctx_idx = (ctx << 1) + sig_mag;
@@ -160,7 +158,7 @@
   int count =
       get_level_count_mag(&mag, tcoeffs, bwl, height, row, col, level_minus_1,
                           base_ref_offset, BASE_CONTEXT_POSITION_NUM);
-  int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag, level);
+  int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag > level);
   return ctx_idx;
 }
 
@@ -429,4 +427,6 @@
 
 void av1_adapt_txb_probs(AV1_COMMON *cm, unsigned int count_sat,
                          unsigned int update_factor);
+
+void av1_init_lv_map(AV1_COMMON *cm);
 #endif  // AV1_COMMON_TXB_COMMON_H_
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index e7661e6..5f2e3d5 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -448,6 +448,8 @@
   const int bwl = txb_info->bwl;
   const int height = txb_info->height;
   tran_low_t *qcoeff = txb_info->qcoeff;
+  const BASE_CTX_TABLE *base_ctx_table =
+      txb_info->coeff_ctx_table->base_ctx_table;
   for (int c = 0; c < txb_info->eob; ++c) {
     const int coeff_idx = scan[c];  // raster order
     const int row = coeff_idx >> bwl;
@@ -469,7 +471,7 @@
       txb_cache->base_count_arr[i][coeff_idx] = count[i];
       const int level = i + 1;
       txb_cache->base_ctx_arr[i][coeff_idx] =
-          get_base_ctx_from_count_mag(row, col, count[i], base_mag[0], level);
+          base_ctx_table[row != 0][col != 0][base_mag[0] > level][count[i]];
     }
 
     // gen_br_count_mag_arr
@@ -609,6 +611,8 @@
                                         const TxbInfo *txb_info) {
   const tran_low_t qc = txb_info->qcoeff[coeff_idx];
   const tran_low_t abs_qc = abs(qc);
+  const BASE_CTX_TABLE *base_ctx_table =
+      txb_info->coeff_ctx_table->base_ctx_table;
 
   int cost_diff = 0;
   for (int base_idx = 0; base_idx < NUM_BASE_LEVELS; ++base_idx) {
@@ -633,7 +637,7 @@
           abs_qc, ctx, txb_costs->base_cost[base_idx][ctx], base_idx);
 
       const int new_ctx =
-          get_base_ctx_from_count_mag(row, col, new_count, new_mag, level);
+          base_ctx_table[row != 0][col != 0][new_mag > level][new_count];
       const int new_cost = get_base_cost(
           abs_qc, new_ctx, txb_costs->base_cost[base_idx][new_ctx], base_idx);
       cost_diff += -org_cost + new_cost;
@@ -977,6 +981,8 @@
     }
   }
 
+  const BASE_CTX_TABLE *base_ctx_table =
+      txb_info->coeff_ctx_table->base_ctx_table;
   for (int i = 0; i < BASE_CONTEXT_POSITION_NUM; ++i) {
     const int nb_row = row - base_ref_offset[i][0];
     const int nb_col = col - base_ref_offset[i][1];
@@ -1003,7 +1009,7 @@
         }
         const int count = txb_cache->base_count_arr[base_idx][nb_coeff_idx];
         txb_cache->base_ctx_arr[base_idx][nb_coeff_idx] =
-            get_base_ctx_from_count_mag(nb_row, nb_col, count, mag, level);
+            base_ctx_table[nb_row != 0][nb_col != 0][mag > level][count];
         // int ref_ctx = get_base_ctx(txb_info->qcoeff, nb_coeff_idx,
         // txb_info->bwl, level);
         // if (ref_ctx != txb_cache->base_ctx_arr[base_idx][nb_coeff_idx]) {
@@ -1410,9 +1416,10 @@
   const int64_t rdmult =
       (x->rdmult * plane_rd_mult[is_inter][plane_type] + 2) >> 2;
 
-  TxbInfo txb_info = { qcoeff,  dqcoeff, tcoeff,     dequant, shift,
-                       tx_size, txs_ctx, bwl,        stride,  height,
-                       eob,     seg_eob, scan_order, txb_ctx, rdmult };
+  TxbInfo txb_info = { qcoeff,     dqcoeff, tcoeff,  dequant,
+                       shift,      tx_size, txs_ctx, bwl,
+                       stride,     height,  eob,     seg_eob,
+                       scan_order, txb_ctx, rdmult,  &cm->coeff_ctx_table };
 
   TxbCache txb_cache;
   gen_txb_cache(&txb_cache, &txb_info);
diff --git a/av1/encoder/encodetxb.h b/av1/encoder/encodetxb.h
index d49b1d8..f68e75a 100644
--- a/av1/encoder/encodetxb.h
+++ b/av1/encoder/encodetxb.h
@@ -39,6 +39,7 @@
   const SCAN_ORDER *scan_order;
   TXB_CTX *txb_ctx;
   int64_t rdmult;
+  const LV_MAP_CTX_TABLE *coeff_ctx_table;
 } TxbInfo;
 
 typedef struct TxbCache {
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 7240c45..082c906 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -27,6 +27,9 @@
 #include "av1/common/entropymv.h"
 #include "av1/common/quant_common.h"
 #include "av1/common/reconinter.h"  // av1_setup_dst_planes()
+#if CONFIG_LV_MAP
+#include "av1/common/txb_common.h"
+#endif
 #include "av1/encoder/av1_quantize.h"
 #include "av1/encoder/aq_variance.h"
 #include "av1/encoder/block.h"
@@ -623,6 +626,9 @@
   }
 
   av1_init_mv_probs(cm);
+#if CONFIG_LV_MAP
+  av1_init_lv_map(cm);
+#endif
 #if CONFIG_ADAPT_SCAN
   av1_init_scan_order(cm);
   av1_deliver_eob_threshold(cm, xd);