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/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]);
 }