LPF_SB: two options for filter level

(1) USE_GUESS_LEVEL = 0: each superblock search and apply best
deblocking filter level. Filter level is transmitted each superblock.

(2) USE_GUESS_LEVEL = 1: use q to guess a filter level for the whole
frame. Only one filter level is transmitted.

Change-Id: I585f6ca0621f5c88fc9d0d95c4fc671114b384c4
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 047e6d4..06cad9e 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -108,7 +108,7 @@
 #define FILT_BOUNDARY_OFFSET 8
 #define FILT_BOUNDARY_MI_OFFSET (FILT_BOUNDARY_OFFSET >> MI_SIZE_LOG2)
 
-#define FAKE_FILTER_LEVEL 10
+#define USE_GUESS_LEVEL 1
 #define USE_LOOP_FILTER_SUPERBLOCK 1
 #endif  // CONFIG_LPF_SB
 
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 39cd3c3..cb5dbbf 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -837,7 +837,7 @@
 #endif  // CONFIG_EXT_PARTITION_TYPES
 
 #if CONFIG_LPF_SB
-  if (bsize == cm->sb_size) {
+  if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
     int filt_lvl;
     if (mi_row == 0 && mi_col == 0) {
       filt_lvl = aom_read_literal(r, 6, ACCT_STR);
@@ -1158,7 +1158,6 @@
   if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
 #endif  // CONFIG_INTRABC
   struct loopfilter *lf = &cm->lf;
-#if !CONFIG_LPF_SB
 #if CONFIG_LOOPFILTER_LEVEL
   lf->filter_level[0] = aom_rb_read_literal(rb, 6);
   lf->filter_level[1] = aom_rb_read_literal(rb, 6);
@@ -1167,9 +1166,12 @@
     lf->filter_level_v = aom_rb_read_literal(rb, 6);
   }
 #else
+#if CONFIG_LPF_SB
+  if (USE_GUESS_LEVEL) lf->filter_level = aom_rb_read_literal(rb, 6);
+#else
   lf->filter_level = aom_rb_read_literal(rb, 6);
-#endif
 #endif  // CONFIG_LPF_SB
+#endif
   lf->sharpness_level = aom_rb_read_literal(rb, 3);
 
   // Read in loop filter deltas applied at the MB level based on mode or ref
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index c1e99cf..5485849 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2370,7 +2370,7 @@
 
 #if CONFIG_LPF_SB
   // send filter level for each superblock (64x64)
-  if (bsize == cm->sb_size) {
+  if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
     if (mi_row == 0 && mi_col == 0) {
       aom_write_literal(w, cm->mi[0].mbmi.filt_lvl, 6);
       cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl = 0;
@@ -2661,7 +2661,6 @@
   struct loopfilter *lf = &cm->lf;
 
 // Encode the loop filter level and type
-#if !CONFIG_LPF_SB
 #if CONFIG_LOOPFILTER_LEVEL
   aom_wb_write_literal(wb, lf->filter_level[0], 6);
   aom_wb_write_literal(wb, lf->filter_level[1], 6);
@@ -2670,9 +2669,12 @@
     aom_wb_write_literal(wb, lf->filter_level_v, 6);
   }
 #else
+#if CONFIG_LPF_SB
+  if (USE_GUESS_LEVEL) aom_wb_write_literal(wb, lf->filter_level, 6);
+#else
   aom_wb_write_literal(wb, lf->filter_level, 6);
-#endif  // CONFIG_LOOPFILTER_LEVEL
 #endif  // CONFIG_LPF_SB
+#endif  // CONFIG_LOOPFILTER_LEVEL
   aom_wb_write_literal(wb, lf->sharpness_level, 3);
 
   // Write out loop filter deltas applied at the MB level based on mode or
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index e2a401e..fdd69a4 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -3372,21 +3372,28 @@
     }
 #if CONFIG_LPF_SB
     if (USE_LOOP_FILTER_SUPERBLOCK) {
-      // apply deblocking filtering right after each superblock is encoded.
-      int last_lvl;
-      if (mi_row == 0 && mi_col == 0) {
-        last_lvl = 0;
+      int filter_lvl;
+
+      if (USE_GUESS_LEVEL) {
+        struct loopfilter *lf = &cpi->common.lf;
+        filter_lvl = lf->filter_level;
       } else {
-        if (mi_col == 0) {
-          last_lvl =
-              cm->mi[(mi_row - MAX_MIB_SIZE) * cm->mi_stride].mbmi.filt_lvl;
+        // apply deblocking filtering right after each superblock is encoded.
+        int last_lvl;
+        if (mi_row == 0 && mi_col == 0) {
+          last_lvl = 0;
         } else {
-          last_lvl = cm->mi[mi_row * cm->mi_stride + mi_col - MAX_MIB_SIZE]
-                         .mbmi.filt_lvl;
+          if (mi_col == 0) {
+            last_lvl =
+                cm->mi[(mi_row - MAX_MIB_SIZE) * cm->mi_stride].mbmi.filt_lvl;
+          } else {
+            last_lvl = cm->mi[mi_row * cm->mi_stride + mi_col - MAX_MIB_SIZE]
+                           .mbmi.filt_lvl;
+          }
         }
+        filter_lvl = av1_search_filter_level(cpi->source, cpi, 1, NULL, mi_row,
+                                             mi_col, last_lvl);
       }
-      const int filter_lvl = av1_search_filter_level(cpi->source, cpi, 1, NULL,
-                                                     mi_row, mi_col, last_lvl);
       av1_loop_filter_frame(get_frame_new_buffer(cm), cm, xd, filter_lvl, 0, 1,
                             mi_row, mi_col);
       // if filter_lvl is 0, we still need to set mi info
@@ -3562,6 +3569,7 @@
 
 #if CONFIG_LPF_SB
   cm->frame_to_show = get_frame_new_buffer(cm);
+  av1_pick_filter_level(cpi->source, cpi, LPF_PICK_FROM_Q);
 #endif
 
   for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
diff --git a/av1/encoder/picklpf.c b/av1/encoder/picklpf.c
index 5b74efa..b064ddb 100644
--- a/av1/encoder/picklpf.c
+++ b/av1/encoder/picklpf.c
@@ -473,7 +473,6 @@
         int lvl =
             search_filter_level(sd, cpi, 1, NULL, mi_row, mi_col, last_lvl);
 #endif
-        if (USE_LOOP_FILTER_SUPERBLOCK) lvl = FAKE_FILTER_LEVEL;
 
         av1_loop_filter_sb_level_init(cm, mi_row, mi_col, lvl);