Expose av1_loop_restoration_filter_unit in restoration.h

This patch also does a certain amount of rejigging for loop
restoration coefficients, grouping the information for a given
restoration unit into a structure called RestorationUnitInfo. The end
result is to completely dispense with the RestorationInternal
structure.

The copy_tile functions in restoration.c, together with those
functions that operate on a single stripe, have been changed so that
they take pointers to the top-left corner of the area on which they
should work, together with a width and height.

The same isn't true of av1_loop_restoration_filter_unit, which still
takes pointers to the top-left of the tile. This is because you
actually need the absolute position in the tile in order to do striped
loop restoration properly.

Change-Id: I768c182cd15c9b2d6cfabb5ffca697cd2a3ff9e1
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index f90f3f1..4cf657e 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -141,8 +141,8 @@
   int nhtiles, nvtiles;
   av1_get_rest_ntiles(width, height, rtile_size, &nhtiles, &nvtiles);
 
-  av1_loop_restoration_frame(cm->frame_to_show, cm, rsi, components_pattern,
-                             dst_frame);
+  av1_loop_restoration_filter_frame(cm->frame_to_show, cm, rsi,
+                                    components_pattern, dst_frame);
   RestorationTileLimits limits = av1_get_rest_tile_limits(
       tile_idx, nhtiles, nvtiles, rtile_size, width, height, ss_y);
   int64_t filt_err = sse_restoration_tile(
@@ -158,8 +158,8 @@
                                      YV12_BUFFER_CONFIG *dst_frame) {
   AV1_COMMON *const cm = &cpi->common;
   int64_t filt_err;
-  av1_loop_restoration_frame(cm->frame_to_show, cm, rsi, components_pattern,
-                             dst_frame);
+  av1_loop_restoration_filter_frame(cm->frame_to_show, cm, rsi,
+                                    components_pattern, dst_frame);
   filt_err = sse_restoration_frame(cm, src, dst_frame, components_pattern);
   return filt_err;
 }
@@ -557,8 +557,6 @@
   const MACROBLOCK *const x = &ctxt->cpi->td.mb;
   const AV1_COMMON *const cm = &ctxt->cpi->common;
   RestorationInfo *rsi = ctxt->cpi->rst_search;
-  SgrprojInfo *sgrproj_info = ctxt->info->sgrproj_info;
-
   SgrprojInfo *ref_sgrproj_info = (SgrprojInfo *)arg;
 
   int64_t err =
@@ -570,8 +568,8 @@
   double cost_norestore = RDCOST_DBL(x->rdmult, (bits >> 4), err);
   ctxt->best_tile_cost[rtile_idx] = INT64_MAX;
 
-  RestorationInfo *plane_rsi = &rsi[ctxt->plane];
-  SgrprojInfo *rtile_sgrproj_info = &plane_rsi->sgrproj_info[rtile_idx];
+  RestorationUnitInfo *plane_rui = &rsi[ctxt->plane].unit_info[rtile_idx];
+  SgrprojInfo *rtile_sgrproj_info = &plane_rui->sgrproj_info;
   uint8_t *dgd_start =
       ctxt->dgd_buffer + limits->v_start * ctxt->dgd_stride + limits->h_start;
   const uint8_t *src_start =
@@ -588,23 +586,22 @@
 #endif  // CONFIG_HIGHBITDEPTH
       rsi[ctxt->plane].procunit_width, rsi[ctxt->plane].procunit_height,
       &rtile_sgrproj_info->ep, rtile_sgrproj_info->xqd, cm->rst_tmpbuf);
-  plane_rsi->restoration_type[rtile_idx] = RESTORE_SGRPROJ;
+  plane_rui->restoration_type = RESTORE_SGRPROJ;
   err = try_restoration_tile(ctxt->src, ctxt->cpi, rsi, (1 << ctxt->plane),
                              rtile_idx, ctxt->dst_frame);
-  bits =
-      count_sgrproj_bits(&plane_rsi->sgrproj_info[rtile_idx], ref_sgrproj_info)
-      << AV1_PROB_COST_SHIFT;
+  bits = count_sgrproj_bits(rtile_sgrproj_info, ref_sgrproj_info)
+         << AV1_PROB_COST_SHIFT;
   bits += x->sgrproj_restore_cost[1];
   double cost_sgrproj = RDCOST_DBL(x->rdmult, (bits >> 4), err);
   if (cost_sgrproj >= cost_norestore) {
     ctxt->type[rtile_idx] = RESTORE_NONE;
   } else {
     ctxt->type[rtile_idx] = RESTORE_SGRPROJ;
-    *ref_sgrproj_info = sgrproj_info[rtile_idx] =
-        plane_rsi->sgrproj_info[rtile_idx];
+    SgrprojInfo *sgrproj_info = &ctxt->info->unit_info[rtile_idx].sgrproj_info;
+    *ref_sgrproj_info = *sgrproj_info = plane_rui->sgrproj_info;
     ctxt->best_tile_cost[rtile_idx] = err;
   }
-  plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE;
+  plane_rui->restoration_type = RESTORE_NONE;
 }
 
 static double search_sgrproj(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
@@ -619,7 +616,7 @@
   RestorationInfo *plane_rsi = &cpi->rst_search[plane];
   plane_rsi->frame_restoration_type = RESTORE_SGRPROJ;
   for (int rtile_idx = 0; rtile_idx < nrtiles; ++rtile_idx) {
-    plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE;
+    plane_rsi->unit_info[rtile_idx].restoration_type = RESTORE_NONE;
   }
 
   // Compute best Sgrproj filters for each rtile, one (encoder/decoder)
@@ -646,20 +643,21 @@
   // Cost for Sgrproj filtering
   SgrprojInfo ref_sgrproj_info;
   set_default_sgrproj(&ref_sgrproj_info);
-  SgrprojInfo *sgrproj_info = info->sgrproj_info;
 
   int bits = frame_level_restore_bits[plane_rsi->frame_restoration_type]
              << AV1_PROB_COST_SHIFT;
   for (int rtile_idx = 0; rtile_idx < nrtiles; ++rtile_idx) {
+    RestorationUnitInfo *plane_rui = &plane_rsi->unit_info[rtile_idx];
+    RestorationUnitInfo *search_rui = &info->unit_info[rtile_idx];
+
     bits += x->sgrproj_restore_cost[type[rtile_idx] != RESTORE_NONE];
-    plane_rsi->sgrproj_info[rtile_idx] = sgrproj_info[rtile_idx];
+    plane_rui->sgrproj_info = search_rui->sgrproj_info;
     if (type[rtile_idx] == RESTORE_SGRPROJ) {
-      bits += count_sgrproj_bits(&plane_rsi->sgrproj_info[rtile_idx],
-                                 &ref_sgrproj_info)
+      bits += count_sgrproj_bits(&plane_rui->sgrproj_info, &ref_sgrproj_info)
               << AV1_PROB_COST_SHIFT;
-      ref_sgrproj_info = plane_rsi->sgrproj_info[rtile_idx];
+      ref_sgrproj_info = plane_rui->sgrproj_info;
     }
-    plane_rsi->restoration_type[rtile_idx] = type[rtile_idx];
+    plane_rui->restoration_type = type[rtile_idx];
   }
   int64_t err =
       try_restoration_frame(src, cpi, cpi->rst_search, (1 << plane), dst_frame);
@@ -1038,21 +1036,25 @@
                     WIENER_FILT_TAP2_MINV };
   int tap_max[] = { WIENER_FILT_TAP0_MAXV, WIENER_FILT_TAP1_MAXV,
                     WIENER_FILT_TAP2_MAXV };
+
+  RestorationUnitInfo *plane_rui = &rsi[plane].unit_info[tile_idx];
+  WienerInfo *plane_wiener = &plane_rui->wiener_info;
+
   // printf("err  pre = %"PRId64"\n", err);
   for (int s = start_step; s >= 1; s >>= 1) {
     for (int p = plane_off; p < WIENER_HALFWIN; ++p) {
       int skip = 0;
       do {
-        if (rsi[plane].wiener_info[tile_idx].hfilter[p] - s >= tap_min[p]) {
-          rsi[plane].wiener_info[tile_idx].hfilter[p] -= s;
-          rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= s;
-          rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2 * s;
+        if (plane_wiener->hfilter[p] - s >= tap_min[p]) {
+          plane_wiener->hfilter[p] -= s;
+          plane_wiener->hfilter[WIENER_WIN - p - 1] -= s;
+          plane_wiener->hfilter[WIENER_HALFWIN] += 2 * s;
           err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, tile_idx,
                                       dst_frame);
           if (err2 > err) {
-            rsi[plane].wiener_info[tile_idx].hfilter[p] += s;
-            rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += s;
-            rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2 * s;
+            plane_wiener->hfilter[p] += s;
+            plane_wiener->hfilter[WIENER_WIN - p - 1] += s;
+            plane_wiener->hfilter[WIENER_HALFWIN] -= 2 * s;
           } else {
             err = err2;
             skip = 1;
@@ -1064,16 +1066,16 @@
       } while (1);
       if (skip) break;
       do {
-        if (rsi[plane].wiener_info[tile_idx].hfilter[p] + s <= tap_max[p]) {
-          rsi[plane].wiener_info[tile_idx].hfilter[p] += s;
-          rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += s;
-          rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2 * s;
+        if (plane_wiener->hfilter[p] + s <= tap_max[p]) {
+          plane_wiener->hfilter[p] += s;
+          plane_wiener->hfilter[WIENER_WIN - p - 1] += s;
+          plane_wiener->hfilter[WIENER_HALFWIN] -= 2 * s;
           err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, tile_idx,
                                       dst_frame);
           if (err2 > err) {
-            rsi[plane].wiener_info[tile_idx].hfilter[p] -= s;
-            rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= s;
-            rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2 * s;
+            plane_wiener->hfilter[p] -= s;
+            plane_wiener->hfilter[WIENER_WIN - p - 1] -= s;
+            plane_wiener->hfilter[WIENER_HALFWIN] += 2 * s;
           } else {
             err = err2;
             // At the highest step size continue moving in the same direction
@@ -1086,16 +1088,16 @@
     for (int p = plane_off; p < WIENER_HALFWIN; ++p) {
       int skip = 0;
       do {
-        if (rsi[plane].wiener_info[tile_idx].vfilter[p] - s >= tap_min[p]) {
-          rsi[plane].wiener_info[tile_idx].vfilter[p] -= s;
-          rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= s;
-          rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2 * s;
+        if (plane_wiener->vfilter[p] - s >= tap_min[p]) {
+          plane_wiener->vfilter[p] -= s;
+          plane_wiener->vfilter[WIENER_WIN - p - 1] -= s;
+          plane_wiener->vfilter[WIENER_HALFWIN] += 2 * s;
           err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, tile_idx,
                                       dst_frame);
           if (err2 > err) {
-            rsi[plane].wiener_info[tile_idx].vfilter[p] += s;
-            rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += s;
-            rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2 * s;
+            plane_wiener->vfilter[p] += s;
+            plane_wiener->vfilter[WIENER_WIN - p - 1] += s;
+            plane_wiener->vfilter[WIENER_HALFWIN] -= 2 * s;
           } else {
             err = err2;
             skip = 1;
@@ -1107,16 +1109,16 @@
       } while (1);
       if (skip) break;
       do {
-        if (rsi[plane].wiener_info[tile_idx].vfilter[p] + s <= tap_max[p]) {
-          rsi[plane].wiener_info[tile_idx].vfilter[p] += s;
-          rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += s;
-          rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2 * s;
+        if (plane_wiener->vfilter[p] + s <= tap_max[p]) {
+          plane_wiener->vfilter[p] += s;
+          plane_wiener->vfilter[WIENER_WIN - p - 1] += s;
+          plane_wiener->vfilter[WIENER_HALFWIN] -= 2 * s;
           err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, tile_idx,
                                       dst_frame);
           if (err2 > err) {
-            rsi[plane].wiener_info[tile_idx].vfilter[p] -= s;
-            rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= s;
-            rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2 * s;
+            plane_wiener->vfilter[p] -= s;
+            plane_wiener->vfilter[WIENER_WIN - p - 1] -= s;
+            plane_wiener->vfilter[WIENER_HALFWIN] += 2 * s;
           } else {
             err = err2;
             // At the highest step size continue moving in the same direction
@@ -1177,8 +1179,8 @@
     return;
   }
 
-  RestorationInfo *plane_rsi = &rsi[ctxt->plane];
-  WienerInfo *rtile_wiener_info = &plane_rsi->wiener_info[rtile_idx];
+  RestorationUnitInfo *plane_rui = &rsi[ctxt->plane].unit_info[rtile_idx];
+  WienerInfo *rtile_wiener_info = &plane_rui->wiener_info;
   quantize_sym_filter(wiener_win, vfilterd, rtile_wiener_info->vfilter);
   quantize_sym_filter(wiener_win, hfilterd, rtile_wiener_info->hfilter);
 
@@ -1193,7 +1195,7 @@
   }
   aom_clear_system_state();
 
-  plane_rsi->restoration_type[rtile_idx] = RESTORE_WIENER;
+  plane_rui->restoration_type = RESTORE_WIENER;
   err = finer_tile_search_wiener(ctxt->src, ctxt->cpi, rsi, 4, ctxt->plane,
                                  wiener_win, rtile_idx, ctxt->dst_frame);
   if (wiener_win != WIENER_WIN) {
@@ -1210,10 +1212,11 @@
     ctxt->type[rtile_idx] = RESTORE_NONE;
   } else {
     ctxt->type[rtile_idx] = RESTORE_WIENER;
-    *ref_wiener_info = ctxt->info->wiener_info[rtile_idx] = *rtile_wiener_info;
+    *ref_wiener_info = ctxt->info->unit_info[rtile_idx].wiener_info =
+        *rtile_wiener_info;
     ctxt->best_tile_cost[rtile_idx] = err;
   }
-  plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE;
+  plane_rui->restoration_type = RESTORE_NONE;
 }
 
 static double search_wiener(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi,
@@ -1228,7 +1231,7 @@
   RestorationInfo *plane_rsi = &cpi->rst_search[plane];
   plane_rsi->frame_restoration_type = RESTORE_WIENER;
   for (int tile_idx = 0; tile_idx < nrtiles; ++tile_idx) {
-    plane_rsi->restoration_type[tile_idx] = RESTORE_NONE;
+    plane_rsi->unit_info[tile_idx].restoration_type = RESTORE_NONE;
   }
 
   AV1_COMMON *const cm = &cpi->common;
@@ -1260,21 +1263,21 @@
   set_default_wiener(&ref_wiener_info);
   int bits = frame_level_restore_bits[plane_rsi->frame_restoration_type]
              << AV1_PROB_COST_SHIFT;
-  WienerInfo *wiener_info = info->wiener_info;
   const int wiener_win =
       (plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA;
 
   for (int tile_idx = 0; tile_idx < nrtiles; ++tile_idx) {
     bits += x->wiener_restore_cost[type[tile_idx] != RESTORE_NONE];
-    plane_rsi->wiener_info[tile_idx] = wiener_info[tile_idx];
+    RestorationUnitInfo *plane_rui = &plane_rsi->unit_info[tile_idx];
+    plane_rui->wiener_info = info->unit_info[tile_idx].wiener_info;
 
     if (type[tile_idx] == RESTORE_WIENER) {
-      bits += count_wiener_bits(wiener_win, &plane_rsi->wiener_info[tile_idx],
+      bits += count_wiener_bits(wiener_win, &plane_rui->wiener_info,
                                 &ref_wiener_info)
               << AV1_PROB_COST_SHIFT;
-      ref_wiener_info = plane_rsi->wiener_info[tile_idx];
+      ref_wiener_info = plane_rui->wiener_info;
     }
-    plane_rsi->restoration_type[tile_idx] = type[tile_idx];
+    plane_rui->restoration_type = type[tile_idx];
   }
   int64_t err =
       try_restoration_frame(src, cpi, cpi->rst_search, 1 << plane, dst_frame);
@@ -1336,7 +1339,8 @@
                                         const RestorationTileLimits *limits,
                                         void *arg) {
   const MACROBLOCK *x = &ctxt->cpi->td.mb;
-  RestorationInfo *rsi = &ctxt->cpi->common.rst_info[ctxt->plane];
+  RestorationUnitInfo *rui =
+      &ctxt->cpi->common.rst_info[ctxt->plane].unit_info[rtile_idx];
   struct switchable_rest_search_ctxt *swctxt =
       (struct switchable_rest_search_ctxt *)arg;
 
@@ -1345,7 +1349,8 @@
   double best_cost =
       RDCOST_DBL(x->rdmult, (x->switchable_restore_cost[RESTORE_NONE] >> 4),
                  swctxt->tile_cost[RESTORE_NONE][rtile_idx]);
-  rsi->restoration_type[rtile_idx] = RESTORE_NONE;
+
+  rui->restoration_type = RESTORE_NONE;
   for (RestorationType r = 1; r < RESTORE_SWITCHABLE_TYPES; r++) {
     if (force_restore_type != RESTORE_TYPES)
       if (r != force_restore_type) continue;
@@ -1354,27 +1359,26 @@
     if (r == RESTORE_WIENER)
       tilebits += count_wiener_bits(
           (ctxt->plane == AOM_PLANE_Y ? WIENER_WIN : WIENER_WIN - 2),
-          &rsi->wiener_info[rtile_idx], &swctxt->wiener_info);
+          &rui->wiener_info, &swctxt->wiener_info);
     else if (r == RESTORE_SGRPROJ)
-      tilebits += count_sgrproj_bits(&rsi->sgrproj_info[rtile_idx],
-                                     &swctxt->sgrproj_info);
+      tilebits += count_sgrproj_bits(&rui->sgrproj_info, &swctxt->sgrproj_info);
     tilebits <<= AV1_PROB_COST_SHIFT;
     tilebits += x->switchable_restore_cost[r];
     double cost =
         RDCOST_DBL(x->rdmult, tilebits >> 4, swctxt->tile_cost[r][rtile_idx]);
 
     if (cost < best_cost) {
-      rsi->restoration_type[rtile_idx] = r;
+      rui->restoration_type = r;
       best_cost = cost;
     }
   }
-  if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER)
-    swctxt->wiener_info = rsi->wiener_info[rtile_idx];
-  else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ)
-    swctxt->sgrproj_info = rsi->sgrproj_info[rtile_idx];
+  if (rui->restoration_type == RESTORE_WIENER)
+    swctxt->wiener_info = rui->wiener_info;
+  else if (rui->restoration_type == RESTORE_SGRPROJ)
+    swctxt->sgrproj_info = rui->sgrproj_info;
   if (force_restore_type != RESTORE_TYPES)
-    assert(rsi->restoration_type[rtile_idx] == force_restore_type ||
-           rsi->restoration_type[rtile_idx] == RESTORE_NONE);
+    assert(rui->restoration_type == force_restore_type ||
+           rui->restoration_type == RESTORE_NONE);
   swctxt->cost_switchable += best_cost;
 }
 
@@ -1464,8 +1468,10 @@
       assert(best_restore == force_restore_type ||
              best_restore == RESTORE_NONE);
     if (best_restore != RESTORE_SWITCHABLE) {
-      memcpy(cm->rst_info[plane].restoration_type, restore_types[best_restore],
-             ntiles * sizeof(restore_types[best_restore][0]));
+      for (int u = 0; u < ntiles; ++u) {
+        cm->rst_info[plane].unit_info[u].restoration_type =
+            restore_types[best_restore][u];
+      }
     }
   }
   /*