Replace bilateral filter with domain transform RF

The main objective is to reduce computational complexity.
The domain transform filter has an effect of edge preserving smoothing
at a lower computational cost than the bilateral filter, and can be
readily paralelized.

A little drop in coding efficiency about 0.06% for lowres, 0.16% for
midres.

Change-Id: Id949406b7e5afe9b64588d130065c63a76e4f3f9
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index 9930da3..86051c8 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -90,8 +90,6 @@
 void av1_free_restoration_buffers(AV1_COMMON *cm) {
   aom_free(cm->rst_info.restoration_type);
   cm->rst_info.restoration_type = NULL;
-  aom_free(cm->rst_info.bilateral_info);
-  cm->rst_info.bilateral_info = NULL;
   aom_free(cm->rst_info.wiener_info);
   cm->rst_info.wiener_info = NULL;
   aom_free(cm->rst_info.sgrproj_info);
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 9aeb408..28f67a4 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1204,20 +1204,13 @@
 #if CONFIG_LOOP_RESTORATION
 const aom_tree_index av1_switchable_restore_tree[TREE_SIZE(
     RESTORE_SWITCHABLE_TYPES)] = {
-  // -RESTORE_NONE, 2, -RESTORE_SGRPROJ, 4, -RESTORE_BILATERAL, -RESTORE_WIENER,
-  -RESTORE_NONE,
-  2,
-  4,
-  6,
-  -RESTORE_SGRPROJ,
-  -RESTORE_DOMAINTXFMRF,
-  -RESTORE_BILATERAL,
-  -RESTORE_WIENER,
+  -RESTORE_NONE, 2, -RESTORE_WIENER, 4, -RESTORE_SGRPROJ, -RESTORE_DOMAINTXFMRF,
 };
 
-static const aom_prob default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES -
-                                                      1] = { 32, 128, 128,
-                                                             128 };
+static const aom_prob
+    default_switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1] = {
+      32, 128, 128,
+    };
 #endif  // CONFIG_LOOP_RESTORATION
 
 #if CONFIG_PALETTE
@@ -2113,14 +2106,6 @@
 
   // To force update of the sharpness
   lf->last_sharpness_level = -1;
-#if CONFIG_LOOP_RESTORATION
-  if (cm->rst_info.bilateral_info) {
-    int s;
-    for (i = 0; i < cm->rst_internal.ntiles; ++i)
-      for (s = 0; s < BILATERAL_SUBTILES; ++s)
-        cm->rst_info.bilateral_info[i].level[s] = -1;
-  }
-#endif  // CONFIG_LOOP_RESTORATION
 
   av1_default_coef_probs(cm);
   init_mode_probs(cm->fc);
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 7d91bba..ebea307 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -489,11 +489,10 @@
 #if CONFIG_LOOP_RESTORATION
 typedef enum {
   RESTORE_NONE = 0,
-  RESTORE_SGRPROJ = 1,
-  RESTORE_BILATERAL = 2,
-  RESTORE_WIENER = 3,
-  RESTORE_DOMAINTXFMRF = 4,
-  RESTORE_SWITCHABLE = 5,
+  RESTORE_WIENER = 1,
+  RESTORE_SGRPROJ = 2,
+  RESTORE_DOMAINTXFMRF = 3,
+  RESTORE_SWITCHABLE = 4,
   RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE,
   RESTORE_TYPES,
 } RestorationType;
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index b8e6a93..201e60c 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -30,40 +30,6 @@
   136, 138, 140, 142, 146, 150, 154, 158, 162, 166, 170, 174
 };
 
-#define BILATERAL_PARAM_PRECISION 16
-#define BILATERAL_AMP_RANGE 256
-#define BILATERAL_AMP_RANGE_SYM (2 * BILATERAL_AMP_RANGE + 1)
-
-static uint8_t bilateral_filter_coeffs_r_kf[BILATERAL_LEVELS_KF]
-                                           [BILATERAL_AMP_RANGE_SYM];
-static uint8_t bilateral_filter_coeffs_r[BILATERAL_LEVELS]
-                                        [BILATERAL_AMP_RANGE_SYM];
-static uint8_t bilateral_filter_coeffs_s_kf[BILATERAL_LEVELS_KF]
-                                           [RESTORATION_WIN][RESTORATION_WIN];
-static uint8_t bilateral_filter_coeffs_s[BILATERAL_LEVELS][RESTORATION_WIN]
-                                        [RESTORATION_WIN];
-
-typedef struct bilateral_params {
-  int sigma_x;  // spatial variance x
-  int sigma_y;  // spatial variance y
-  int sigma_r;  // range variance
-} BilateralParamsType;
-
-static BilateralParamsType bilateral_level_to_params_arr[BILATERAL_LEVELS] = {
-  //  Values are rounded to 1/16 th precision
-  { 8, 9, 30 },   { 9, 8, 30 },   { 9, 11, 32 },  { 11, 9, 32 },
-  { 14, 14, 36 }, { 18, 18, 36 }, { 24, 24, 40 }, { 32, 32, 40 },
-};
-
-static BilateralParamsType
-    bilateral_level_to_params_arr_kf[BILATERAL_LEVELS_KF] = {
-      //  Values are rounded to 1/16 th precision
-      { 8, 8, 30 },   { 9, 9, 32 },   { 10, 10, 32 }, { 12, 12, 32 },
-      { 14, 14, 32 }, { 18, 18, 36 }, { 24, 24, 40 }, { 30, 30, 44 },
-      { 36, 36, 48 }, { 42, 42, 48 }, { 48, 48, 48 }, { 48, 48, 56 },
-      { 56, 56, 48 }, { 56, 56, 56 }, { 56, 56, 64 }, { 64, 64, 48 },
-    };
-
 const sgr_params_type sgr_params[SGRPROJ_PARAMS] = {
   // r1, eps1, r2, eps2
   { 2, 27, 1, 11 }, { 2, 31, 1, 12 }, { 2, 37, 1, 12 }, { 2, 44, 1, 12 },
@@ -80,12 +46,6 @@
                                          int bit_depth);
 #endif  // CONFIG_AOM_HIGHBITDEPTH
 
-static INLINE BilateralParamsType av1_bilateral_level_to_params(int index,
-                                                                int kf) {
-  return kf ? bilateral_level_to_params_arr_kf[index]
-            : bilateral_level_to_params_arr[index];
-}
-
 static void GenDomainTxfmRFVtable() {
   int i, j;
   const double sigma_s = sqrt(2.0);
@@ -105,79 +65,7 @@
   }
 }
 
-static void GenBilateralTables() {
-  int i;
-  for (i = 0; i < BILATERAL_LEVELS_KF; i++) {
-    const BilateralParamsType param = av1_bilateral_level_to_params(i, 1);
-    const int sigma_x = param.sigma_x;
-    const int sigma_y = param.sigma_y;
-    const int sigma_r = param.sigma_r;
-    const double sigma_r_d = (double)sigma_r / BILATERAL_PARAM_PRECISION;
-    const double sigma_x_d = (double)sigma_x / BILATERAL_PARAM_PRECISION;
-    const double sigma_y_d = (double)sigma_y / BILATERAL_PARAM_PRECISION;
-
-    uint8_t *fr = bilateral_filter_coeffs_r_kf[i] + BILATERAL_AMP_RANGE;
-    int j, x, y;
-    for (j = 0; j <= BILATERAL_AMP_RANGE; j++) {
-      fr[j] = (uint8_t)(0.5 +
-                        RESTORATION_FILT_STEP *
-                            exp(-(j * j) / (2 * sigma_r_d * sigma_r_d)));
-      fr[-j] = fr[j];
-    }
-    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
-      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
-        bilateral_filter_coeffs_s_kf[i][y + RESTORATION_HALFWIN]
-                                    [x + RESTORATION_HALFWIN] = (uint8_t)(
-                                        0.5 +
-                                        RESTORATION_FILT_STEP *
-                                            exp(-(x * x) / (2 * sigma_x_d *
-                                                            sigma_x_d) -
-                                                (y * y) / (2 * sigma_y_d *
-                                                           sigma_y_d)));
-      }
-    }
-  }
-  for (i = 0; i < BILATERAL_LEVELS; i++) {
-    const BilateralParamsType param = av1_bilateral_level_to_params(i, 0);
-    const int sigma_x = param.sigma_x;
-    const int sigma_y = param.sigma_y;
-    const int sigma_r = param.sigma_r;
-    const double sigma_r_d = (double)sigma_r / BILATERAL_PARAM_PRECISION;
-    const double sigma_x_d = (double)sigma_x / BILATERAL_PARAM_PRECISION;
-    const double sigma_y_d = (double)sigma_y / BILATERAL_PARAM_PRECISION;
-
-    uint8_t *fr = bilateral_filter_coeffs_r[i] + BILATERAL_AMP_RANGE;
-    int j, x, y;
-    for (j = 0; j <= BILATERAL_AMP_RANGE; j++) {
-      fr[j] = (uint8_t)(0.5 +
-                        RESTORATION_FILT_STEP *
-                            exp(-(j * j) / (2 * sigma_r_d * sigma_r_d)));
-      fr[-j] = fr[j];
-    }
-    for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; y++) {
-      for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; x++) {
-        bilateral_filter_coeffs_s[i][y + RESTORATION_HALFWIN]
-                                 [x + RESTORATION_HALFWIN] = (uint8_t)(
-                                     0.5 +
-                                     RESTORATION_FILT_STEP *
-                                         exp(-(x * x) /
-                                                 (2 * sigma_x_d * sigma_x_d) -
-                                             (y * y) /
-                                                 (2 * sigma_y_d * sigma_y_d)));
-      }
-    }
-  }
-}
-
-void av1_loop_restoration_precal() {
-  GenBilateralTables();
-  GenDomainTxfmRFVtable();
-}
-
-int av1_bilateral_level_bits(const AV1_COMMON *const cm) {
-  return cm->frame_type == KEY_FRAME ? BILATERAL_LEVEL_BITS_KF
-                                     : BILATERAL_LEVEL_BITS;
-}
+void av1_loop_restoration_precal() { GenDomainTxfmRFVtable(); }
 
 void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
                                int kf, int width, int height) {
@@ -228,75 +116,6 @@
   }
 }
 
-static void loop_bilateral_filter_tile(uint8_t *data, int tile_idx, int width,
-                                       int height, int stride,
-                                       RestorationInternal *rst,
-                                       uint8_t *tmpdata, int tmpstride) {
-  int i, j, subtile_idx;
-  int h_start, h_end, v_start, v_end;
-  const int tile_width = rst->tile_width >> rst->subsampling_x;
-  const int tile_height = rst->tile_height >> rst->subsampling_y;
-
-  for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
-    uint8_t *data_p, *tmpdata_p;
-    const int level = rst->rsi->bilateral_info[tile_idx].level[subtile_idx];
-    uint8_t(*wx_lut)[RESTORATION_WIN];
-    uint8_t *wr_lut_;
-
-    if (level < 0) continue;
-    wr_lut_ = (rst->keyframe ? bilateral_filter_coeffs_r_kf[level]
-                             : bilateral_filter_coeffs_r[level]) +
-              BILATERAL_AMP_RANGE;
-    wx_lut = rst->keyframe ? bilateral_filter_coeffs_s_kf[level]
-                           : bilateral_filter_coeffs_s[level];
-
-    av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
-                             rst->nhtiles, rst->nvtiles, tile_width,
-                             tile_height, width, height, 1, 1, &h_start, &h_end,
-                             &v_start, &v_end);
-
-    data_p = data + h_start + v_start * stride;
-    tmpdata_p = tmpdata + h_start + v_start * tmpstride;
-
-    for (i = 0; i < (v_end - v_start); ++i) {
-      for (j = 0; j < (h_end - h_start); ++j) {
-        int x, y, wt;
-        int64_t flsum = 0, wtsum = 0;
-        uint8_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-        for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-          for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-            wt = (int)wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
-                 (int)wr_lut_[data_p2[x] - data_p[j]];
-            wtsum += (int64_t)wt;
-            flsum += (int64_t)wt * data_p2[x];
-          }
-          data_p2 += stride;
-        }
-        if (wtsum > 0)
-          tmpdata_p[j] = clip_pixel((int)((flsum + wtsum / 2) / wtsum));
-        else
-          tmpdata_p[j] = data_p[j];
-      }
-      tmpdata_p += tmpstride;
-      data_p += stride;
-    }
-    for (i = v_start; i < v_end; ++i) {
-      memcpy(data + i * stride + h_start, tmpdata + i * tmpstride + h_start,
-             (h_end - h_start) * sizeof(*data));
-    }
-  }
-}
-
-static void loop_bilateral_filter(uint8_t *data, int width, int height,
-                                  int stride, RestorationInternal *rst,
-                                  uint8_t *tmpdata, int tmpstride) {
-  int tile_idx;
-  for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
-    loop_bilateral_filter_tile(data, tile_idx, width, height, stride, rst,
-                               tmpdata, tmpstride);
-  }
-}
-
 uint8_t hor_sym_filter(uint8_t *d, int *hfilter) {
   int32_t s =
       (1 << (RESTORATION_FILT_BITS - 1)) + d[0] * hfilter[RESTORATION_HALFWIN];
@@ -853,10 +672,7 @@
     tmpdata_p += tmpstride;
   }
   for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
-    if (rst->rsi->restoration_type[tile_idx] == RESTORE_BILATERAL) {
-      loop_bilateral_filter_tile(data, tile_idx, width, height, stride, rst,
-                                 tmpdata, tmpstride);
-    } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
+    if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
       loop_wiener_filter_tile(data, tile_idx, width, height, stride, rst,
                               tmpdata, tmpstride);
     } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) {
@@ -871,81 +687,6 @@
 }
 
 #if CONFIG_AOM_HIGHBITDEPTH
-static void loop_bilateral_filter_tile_highbd(uint16_t *data, int tile_idx,
-                                              int width, int height, int stride,
-                                              RestorationInternal *rst,
-                                              uint16_t *tmpdata, int tmpstride,
-                                              int bit_depth) {
-  const int tile_width = rst->tile_width >> rst->subsampling_x;
-  const int tile_height = rst->tile_height >> rst->subsampling_y;
-  int i, j, subtile_idx;
-  int h_start, h_end, v_start, v_end;
-  const int shift = bit_depth - 8;
-
-  for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
-    uint16_t *data_p, *tmpdata_p;
-    const int level = rst->rsi->bilateral_info[tile_idx].level[subtile_idx];
-    uint8_t(*wx_lut)[RESTORATION_WIN];
-    uint8_t *wr_lut_;
-
-    if (level < 0) continue;
-    wr_lut_ = (rst->keyframe ? bilateral_filter_coeffs_r_kf[level]
-                             : bilateral_filter_coeffs_r[level]) +
-              BILATERAL_AMP_RANGE;
-    wx_lut = rst->keyframe ? bilateral_filter_coeffs_s_kf[level]
-                           : bilateral_filter_coeffs_s[level];
-    av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
-                             rst->nhtiles, rst->nvtiles, tile_width,
-                             tile_height, width, height, 1, 1, &h_start, &h_end,
-                             &v_start, &v_end);
-
-    data_p = data + h_start + v_start * stride;
-    tmpdata_p = tmpdata + h_start + v_start * tmpstride;
-
-    for (i = 0; i < (v_end - v_start); ++i) {
-      for (j = 0; j < (h_end - h_start); ++j) {
-        int x, y, wt;
-        int64_t flsum = 0, wtsum = 0;
-        uint16_t *data_p2 = data_p + j - RESTORATION_HALFWIN * stride;
-        for (y = -RESTORATION_HALFWIN; y <= RESTORATION_HALFWIN; ++y) {
-          for (x = -RESTORATION_HALFWIN; x <= RESTORATION_HALFWIN; ++x) {
-            wt = (int)wx_lut[y + RESTORATION_HALFWIN][x + RESTORATION_HALFWIN] *
-                 (int)wr_lut_[(data_p2[x] >> shift) - (data_p[j] >> shift)];
-            wtsum += (int64_t)wt;
-            flsum += (int64_t)wt * data_p2[x];
-          }
-          data_p2 += stride;
-        }
-        if (wtsum > 0)
-          tmpdata_p[j] =
-              clip_pixel_highbd((int)((flsum + wtsum / 2) / wtsum), bit_depth);
-        else
-          tmpdata_p[j] = data_p[j];
-      }
-      tmpdata_p += tmpstride;
-      data_p += stride;
-    }
-    for (i = v_start; i < v_end; ++i) {
-      memcpy(data + i * stride + h_start, tmpdata + i * tmpstride + h_start,
-             (h_end - h_start) * sizeof(*data));
-    }
-  }
-}
-
-static void loop_bilateral_filter_highbd(uint8_t *data8, int width, int height,
-                                         int stride, RestorationInternal *rst,
-                                         uint8_t *tmpdata8, int tmpstride,
-                                         int bit_depth) {
-  int tile_idx;
-  uint16_t *data = CONVERT_TO_SHORTPTR(data8);
-  uint16_t *tmpdata = CONVERT_TO_SHORTPTR(tmpdata8);
-
-  for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
-    loop_bilateral_filter_tile_highbd(data, tile_idx, width, height, stride,
-                                      rst, tmpdata, tmpstride, bit_depth);
-  }
-}
-
 uint16_t hor_sym_filter_highbd(uint16_t *d, int *hfilter, int bd) {
   int32_t s =
       (1 << (RESTORATION_FILT_BITS - 1)) + d[0] * hfilter[RESTORATION_HALFWIN];
@@ -1223,10 +964,7 @@
     tmpdata_p += tmpstride;
   }
   for (tile_idx = 0; tile_idx < rst->ntiles; ++tile_idx) {
-    if (rst->rsi->restoration_type[tile_idx] == RESTORE_BILATERAL) {
-      loop_bilateral_filter_tile_highbd(data, tile_idx, width, height, stride,
-                                        rst, tmpdata, tmpstride, bit_depth);
-    } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
+    if (rst->rsi->restoration_type[tile_idx] == RESTORE_WIENER) {
       loop_wiener_filter_tile_highbd(data, tile_idx, width, height, stride, rst,
                                      tmpdata, tmpstride, bit_depth);
     } else if (rst->rsi->restoration_type[tile_idx] == RESTORE_SGRPROJ) {
@@ -1251,20 +989,14 @@
   const int uvstart = ystart >> cm->subsampling_y;
   int yend = end_mi_row << MI_SIZE_LOG2;
   int uvend = yend >> cm->subsampling_y;
-  restore_func_type restore_funcs[RESTORE_TYPES] = { NULL,
+  restore_func_type restore_funcs[RESTORE_TYPES] = { NULL, loop_wiener_filter,
                                                      loop_sgrproj_filter,
-                                                     loop_bilateral_filter,
-                                                     loop_wiener_filter,
                                                      loop_domaintxfmrf_filter,
                                                      loop_switchable_filter };
 #if CONFIG_AOM_HIGHBITDEPTH
   restore_func_highbd_type restore_funcs_highbd[RESTORE_TYPES] = {
-    NULL,
-    loop_sgrproj_filter_highbd,
-    loop_bilateral_filter_highbd,
-    loop_wiener_filter_highbd,
-    loop_domaintxfmrf_filter_highbd,
-    loop_switchable_filter_highbd
+    NULL, loop_wiener_filter_highbd, loop_sgrproj_filter_highbd,
+    loop_domaintxfmrf_filter_highbd, loop_switchable_filter_highbd
   };
 #endif  // CONFIG_AOM_HIGHBITDEPTH
   restore_func_type restore_func =
diff --git a/av1/common/restoration.h b/av1/common/restoration.h
index 167120b..63e78a1 100644
--- a/av1/common/restoration.h
+++ b/av1/common/restoration.h
@@ -60,14 +60,6 @@
 
 #define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)
 
-#define BILATERAL_LEVEL_BITS_KF 4
-#define BILATERAL_LEVELS_KF (1 << BILATERAL_LEVEL_BITS_KF)
-#define BILATERAL_LEVEL_BITS 3
-#define BILATERAL_LEVELS (1 << BILATERAL_LEVEL_BITS)
-
-#define BILATERAL_SUBTILE_BITS 1
-#define BILATERAL_SUBTILES (1 << (2 * BILATERAL_SUBTILE_BITS))
-
 #define RESTORATION_HALFWIN 3
 #define RESTORATION_HALFWIN1 (RESTORATION_HALFWIN + 1)
 #define RESTORATION_WIN (2 * RESTORATION_HALFWIN + 1)
@@ -94,8 +86,6 @@
 #define WIENER_FILT_TAP2_MAXV \
   (WIENER_FILT_TAP2_MINV - 1 + (1 << WIENER_FILT_TAP2_BITS))
 
-typedef struct { int level[BILATERAL_SUBTILES]; } BilateralInfo;
-
 typedef struct {
   int level;
   int vfilter[RESTORATION_WIN], hfilter[RESTORATION_WIN];
@@ -122,8 +112,6 @@
 typedef struct {
   RestorationType frame_restoration_type;
   RestorationType *restoration_type;
-  // Bilateral filter
-  BilateralInfo *bilateral_info;
   // Wiener filter
   WienerInfo *wiener_info;
   // Selfguided proj filter
@@ -210,7 +198,6 @@
                                          int stride, int param, int bit_depth);
 #endif  // CONFIG_AOM_HIGHBITDEPTH
 void decode_xq(int *xqd, int *xq);
-int av1_bilateral_level_bits(const struct AV1Common *const cm);
 void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
                                int kf, int width, int height);
 void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index e35bda6..f6111f3 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2268,11 +2268,9 @@
   if (aom_rb_read_bit(rb)) {
     if (aom_rb_read_bit(rb))
       rsi->frame_restoration_type =
-          (aom_rb_read_bit(rb) ? RESTORE_WIENER : RESTORE_BILATERAL);
-    else
-      rsi->frame_restoration_type =
           (aom_rb_read_bit(rb) ? RESTORE_DOMAINTXFMRF : RESTORE_SGRPROJ);
-    // rsi->frame_restoration_type = RESTORE_SGRPROJ;
+    else
+      rsi->frame_restoration_type = RESTORE_WIENER;
   } else {
     rsi->frame_restoration_type =
         aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE;
@@ -2314,20 +2312,6 @@
       aom_read_literal(rb, DOMAINTXFMRF_PARAMS_BITS, ACCT_STR);
 }
 
-static void read_bilateral_filter(const AV1_COMMON *cm,
-                                  BilateralInfo *bilateral_info,
-                                  aom_reader *rb) {
-  int s;
-  for (s = 0; s < BILATERAL_SUBTILES; ++s) {
-    if (aom_read(rb, RESTORE_NONE_BILATERAL_PROB, ACCT_STR)) {
-      bilateral_info->level[s] =
-          aom_read_literal(rb, av1_bilateral_level_bits(cm), ACCT_STR);
-    } else {
-      bilateral_info->level[s] = -1;
-    }
-  }
-}
-
 static void decode_restoration(AV1_COMMON *cm, aom_reader *rb) {
   int i;
   RestorationInfo *rsi = &cm->rst_info;
@@ -2337,9 +2321,6 @@
     rsi->restoration_type = (RestorationType *)aom_realloc(
         rsi->restoration_type, sizeof(*rsi->restoration_type) * ntiles);
     if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
-      rsi->bilateral_info = (BilateralInfo *)aom_realloc(
-          rsi->bilateral_info, sizeof(*rsi->bilateral_info) * ntiles);
-      assert(rsi->bilateral_info != NULL);
       rsi->wiener_info = (WienerInfo *)aom_realloc(
           rsi->wiener_info, sizeof(*rsi->wiener_info) * ntiles);
       assert(rsi->wiener_info != NULL);
@@ -2356,13 +2337,6 @@
         if (rsi->restoration_type[i] == RESTORE_WIENER) {
           rsi->wiener_info[i].level = 1;
           read_wiener_filter(&rsi->wiener_info[i], rb);
-        } else if (rsi->restoration_type[i] == RESTORE_BILATERAL) {
-#if BILATERAL_SUBTILES == 0
-          rsi->bilateral_info[i].level[0] =
-              aom_read_literal(rb, av1_bilateral_level_bits(cm), ACCT_STR);
-#else
-          read_bilateral_filter(cm, &rsi->bilateral_info[i], rb);
-#endif
         } else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) {
           rsi->sgrproj_info[i].level = 1;
           read_sgrproj_filter(&rsi->sgrproj_info[i], rb);
@@ -2385,14 +2359,6 @@
           rsi->restoration_type[i] = RESTORE_NONE;
         }
       }
-    } else if (rsi->frame_restoration_type == RESTORE_BILATERAL) {
-      rsi->bilateral_info = (BilateralInfo *)aom_realloc(
-          rsi->bilateral_info, sizeof(*rsi->bilateral_info) * ntiles);
-      assert(rsi->bilateral_info != NULL);
-      for (i = 0; i < ntiles; ++i) {
-        rsi->restoration_type[i] = RESTORE_BILATERAL;
-        read_bilateral_filter(cm, &rsi->bilateral_info[i], rb);
-      }
     } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) {
       rsi->sgrproj_info = (SgrprojInfo *)aom_realloc(
           rsi->sgrproj_info, sizeof(*rsi->sgrproj_info) * ntiles);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 72ebc8a..81d8b39 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2991,34 +2991,22 @@
       aom_wb_write_bit(wb, 0);
       aom_wb_write_bit(wb, 0);
       break;
-    case RESTORE_SWITCHABLE:
-      aom_wb_write_bit(wb, 0);
+    case RESTORE_WIENER:
       aom_wb_write_bit(wb, 1);
+      aom_wb_write_bit(wb, 0);
       break;
-    /*
-  case RESTORE_SGRPROJ:
-    aom_wb_write_bit(wb, 1);
-    aom_wb_write_bit(wb, 0);
-    break;
-    */
     case RESTORE_SGRPROJ:
       aom_wb_write_bit(wb, 1);
-      aom_wb_write_bit(wb, 0);
+      aom_wb_write_bit(wb, 1);
       aom_wb_write_bit(wb, 0);
       break;
     case RESTORE_DOMAINTXFMRF:
       aom_wb_write_bit(wb, 1);
-      aom_wb_write_bit(wb, 0);
+      aom_wb_write_bit(wb, 1);
       aom_wb_write_bit(wb, 1);
       break;
-    case RESTORE_BILATERAL:
-      aom_wb_write_bit(wb, 1);
-      aom_wb_write_bit(wb, 1);
+    case RESTORE_SWITCHABLE:
       aom_wb_write_bit(wb, 0);
-      break;
-    case RESTORE_WIENER:
-      aom_wb_write_bit(wb, 1);
-      aom_wb_write_bit(wb, 1);
       aom_wb_write_bit(wb, 1);
       break;
     default: assert(0);
@@ -3053,19 +3041,6 @@
   aom_write_literal(wb, domaintxfmrf_info->sigma_r, DOMAINTXFMRF_PARAMS_BITS);
 }
 
-static void write_bilateral_filter(const AV1_COMMON *cm,
-                                   BilateralInfo *bilateral_info,
-                                   aom_writer *wb) {
-  int s;
-  for (s = 0; s < BILATERAL_SUBTILES; ++s) {
-    aom_write(wb, bilateral_info->level[s] >= 0, RESTORE_NONE_BILATERAL_PROB);
-    if (bilateral_info->level[s] >= 0) {
-      aom_write_literal(wb, bilateral_info->level[s],
-                        av1_bilateral_level_bits(cm));
-    }
-  }
-}
-
 static void encode_restoration(AV1_COMMON *cm, aom_writer *wb) {
   int i;
   RestorationInfo *rsi = &cm->rst_info;
@@ -3076,14 +3051,7 @@
         av1_write_token(
             wb, av1_switchable_restore_tree, cm->fc->switchable_restore_prob,
             &switchable_restore_encodings[rsi->restoration_type[i]]);
-        if (rsi->restoration_type[i] == RESTORE_BILATERAL) {
-#if BILATERAL_SUBTILES == 0
-          aom_write_literal(wb, rsi->bilateral_info[i].level[0],
-                            av1_bilateral_level_bits(cm));
-#else
-          write_bilateral_filter(cm, &rsi->bilateral_info[i], wb);
-#endif
-        } else if (rsi->restoration_type[i] == RESTORE_WIENER) {
+        if (rsi->restoration_type[i] == RESTORE_WIENER) {
           write_wiener_filter(&rsi->wiener_info[i], wb);
         } else if (rsi->restoration_type[i] == RESTORE_SGRPROJ) {
           write_sgrproj_filter(&rsi->sgrproj_info[i], wb);
@@ -3091,10 +3059,6 @@
           write_domaintxfmrf_filter(&rsi->domaintxfmrf_info[i], wb);
         }
       }
-    } else if (rsi->frame_restoration_type == RESTORE_BILATERAL) {
-      for (i = 0; i < cm->rst_internal.ntiles; ++i) {
-        write_bilateral_filter(cm, &rsi->bilateral_info[i], wb);
-      }
     } else if (rsi->frame_restoration_type == RESTORE_WIENER) {
       for (i = 0; i < cm->rst_internal.ntiles; ++i) {
         aom_write(wb, rsi->wiener_info[i].level != 0, RESTORE_NONE_WIENER_PROB);
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 07e738d..64687a2 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -34,8 +34,7 @@
                                       int partial_frame, RestorationInfo *info,
                                       double *best_tile_cost);
 
-// const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 3, 3, 2 };
-const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 3, 3, 3, 3, 2 };
+const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 3, 3, 2 };
 
 static int64_t sse_restoration_tile(const YV12_BUFFER_CONFIG *src,
                                     AV1_COMMON *const cm, int h_start,
@@ -476,7 +475,8 @@
                                   RestorationInfo *info,
                                   double *best_tile_cost) {
   DomaintxfmrfInfo *domaintxfmrf_info = info->domaintxfmrf_info;
-  double err, cost_norestore, cost_domaintxfmrf;
+  double cost_norestore, cost_domaintxfmrf;
+  int64_t err;
   int bits;
   MACROBLOCK *x = &cpi->td.mb;
   AV1_COMMON *const cm = &cpi->common;
@@ -561,116 +561,6 @@
   return cost_domaintxfmrf;
 }
 
-static double search_bilateral(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
-                               int filter_level, int partial_frame,
-                               RestorationInfo *info, double *best_tile_cost) {
-  BilateralInfo *bilateral_info = info->bilateral_info;
-  AV1_COMMON *const cm = &cpi->common;
-  int i, tile_idx, subtile_idx;
-  int64_t err;
-  int bits;
-  double cost, best_cost, cost_bilateral, cost_norestore_subtile;
-  const int bilateral_level_bits = av1_bilateral_level_bits(&cpi->common);
-  const int bilateral_levels = 1 << bilateral_level_bits;
-  MACROBLOCK *x = &cpi->td.mb;
-  RestorationInfo rsi;
-  int tile_width, tile_height, nhtiles, nvtiles;
-  int h_start, h_end, v_start, v_end;
-  const int ntiles = av1_get_rest_ntiles(cm->width, cm->height, &tile_width,
-                                         &tile_height, &nhtiles, &nvtiles);
-
-  //  Make a copy of the unfiltered / processed recon buffer
-  aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
-  av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filter_level,
-                        1, partial_frame);
-  aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_db);
-
-  rsi.frame_restoration_type = RESTORE_BILATERAL;
-  rsi.bilateral_info =
-      (BilateralInfo *)aom_malloc(sizeof(*rsi.bilateral_info) * ntiles);
-  assert(rsi.bilateral_info != NULL);
-
-  for (tile_idx = 0; tile_idx < ntiles; ++tile_idx)
-    for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx)
-      bilateral_info[tile_idx].level[subtile_idx] =
-          rsi.bilateral_info[tile_idx].level[subtile_idx] = -1;
-
-  // Find best filter for each tile
-  for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
-    for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
-      av1_get_rest_tile_limits(tile_idx, subtile_idx, BILATERAL_SUBTILE_BITS,
-                               nhtiles, nvtiles, tile_width, tile_height,
-                               cm->width, cm->height, 0, 0, &h_start, &h_end,
-                               &v_start, &v_end);
-      err = sse_restoration_tile(src, cm, h_start, h_end - h_start, v_start,
-                                 v_end - v_start);
-#if BILATERAL_SUBTILES
-      // #bits when a subtile is not restored
-      bits = av1_cost_bit(RESTORE_NONE_BILATERAL_PROB, 0);
-#else
-      bits = 0;
-#endif
-      cost_norestore_subtile =
-          RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
-      best_cost = cost_norestore_subtile;
-
-      for (i = 0; i < bilateral_levels; ++i) {
-        rsi.bilateral_info[tile_idx].level[subtile_idx] = i;
-        err = try_restoration_tile(src, cpi, &rsi, partial_frame, tile_idx,
-                                   subtile_idx, BILATERAL_SUBTILE_BITS);
-        bits = bilateral_level_bits << AV1_PROB_COST_SHIFT;
-        bits += av1_cost_bit(RESTORE_NONE_BILATERAL_PROB, 1);
-        cost = RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
-        if (cost < best_cost) {
-          bilateral_info[tile_idx].level[subtile_idx] = i;
-          best_cost = cost;
-        }
-        rsi.bilateral_info[tile_idx].level[subtile_idx] = -1;
-      }
-    }
-    bits = 0;
-    for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
-      rsi.bilateral_info[tile_idx].level[subtile_idx] =
-          bilateral_info[tile_idx].level[subtile_idx];
-      if (rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0)
-        bits += bilateral_level_bits << AV1_PROB_COST_SHIFT;
-#if BILATERAL_SUBTILES
-      bits +=
-          av1_cost_bit(RESTORE_NONE_BILATERAL_PROB,
-                       rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0);
-#endif
-    }
-    err = try_restoration_tile(src, cpi, &rsi, partial_frame, tile_idx, 0, 0);
-    best_tile_cost[tile_idx] = RDCOST_DBL(
-        x->rdmult, x->rddiv,
-        (bits + cpi->switchable_restore_cost[RESTORE_BILATERAL]) >> 4, err);
-  }
-  // Find cost for combined configuration
-  bits = frame_level_restore_bits[rsi.frame_restoration_type]
-         << AV1_PROB_COST_SHIFT;
-  for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) {
-    for (subtile_idx = 0; subtile_idx < BILATERAL_SUBTILES; ++subtile_idx) {
-      rsi.bilateral_info[tile_idx].level[subtile_idx] =
-          bilateral_info[tile_idx].level[subtile_idx];
-      if (rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0) {
-        bits += bilateral_level_bits << AV1_PROB_COST_SHIFT;
-      }
-#if BILATERAL_SUBTILES
-      bits +=
-          av1_cost_bit(RESTORE_NONE_BILATERAL_PROB,
-                       rsi.bilateral_info[tile_idx].level[subtile_idx] >= 0);
-#endif
-    }
-  }
-  err = try_restoration_frame(src, cpi, &rsi, partial_frame);
-  cost_bilateral = RDCOST_DBL(x->rdmult, x->rddiv, (bits >> 4), err);
-
-  aom_free(rsi.bilateral_info);
-
-  aom_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
-  return cost_bilateral;
-}
-
 static double find_average(uint8_t *src, int h_start, int h_end, int v_start,
                            int v_end, int stride) {
   uint64_t sum = 0;
@@ -1173,8 +1063,7 @@
 void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
                                  LPF_PICK_METHOD method) {
   static search_restore_type search_restore_fun[RESTORE_SWITCHABLE_TYPES] = {
-    search_norestore, search_sgrproj,      search_bilateral,
-    search_wiener,    search_domaintxfmrf,
+    search_norestore, search_wiener, search_sgrproj, search_domaintxfmrf,
   };
   AV1_COMMON *const cm = &cpi->common;
   struct loopfilter *const lf = &cm->lf;
@@ -1188,10 +1077,6 @@
   cm->rst_info.restoration_type = (RestorationType *)aom_realloc(
       cm->rst_info.restoration_type,
       sizeof(*cm->rst_info.restoration_type) * ntiles);
-  cm->rst_info.bilateral_info = (BilateralInfo *)aom_realloc(
-      cm->rst_info.bilateral_info,
-      sizeof(*cm->rst_info.bilateral_info) * ntiles);
-  assert(cm->rst_info.bilateral_info != NULL);
   cm->rst_info.wiener_info = (WienerInfo *)aom_realloc(
       cm->rst_info.wiener_info, sizeof(*cm->rst_info.wiener_info) * ntiles);
   assert(cm->rst_info.wiener_info != NULL);
@@ -1264,10 +1149,10 @@
   }
   cm->rst_info.frame_restoration_type = best_restore;
   /*
-  printf("Frame %d/%d frame_restore_type %d : %f %f %f %f %f %f\n",
+  printf("Frame %d/%d frame_restore_type %d : %f %f %f %f %f\n",
          cm->current_video_frame, cm->show_frame,
          cm->rst_info.frame_restoration_type, cost_restore[0], cost_restore[1],
-         cost_restore[2], cost_restore[3], cost_restore[4], cost_restore[5]);
+         cost_restore[2], cost_restore[3], cost_restore[4]);
          */
   for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) aom_free(tile_cost[r]);
 }