Create current_unit_stack variable.

This variable points to the most recent list of units with merged
coefficients and is passed through several functions to the functions
that check filter RD-values.

There is also a minor change to thread_common.c to properly disable
multithreading.

Change-Id: Iacbb6338f44ecf05e4c6b7bbfe53eddc2f41cd4d
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index 9081fe5..6d3223f 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -29,6 +29,10 @@
 
 #include "aom_ports/mem.h"
 
+#if CONFIG_RST_MERGECOEFFS
+#include "third_party/vector/vector.h"
+#endif  // CONFIG_RST_MERGECOEFFS
+
 #if CONFIG_WIENER_NONSEP
 #define WIENERNS_PREC_BITS_Y_MINUS7 (WIENERNS_PREC_BITS_Y - 7)
 #define AOM_WIENERNS_COEFF_Y(b, m, k)               \
@@ -1424,7 +1428,15 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                                  RestorationUnitInfo *shared_params,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                                 Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                                  RestorationLineBuffers *rlbs) {
+#if CONFIG_RST_MERGECOEFFS
+  // required in function signature but not needed in this function
+  (void)current_unit_stack;
+#endif  // CONFIG_RST_MERGECOEFFS
+
   FilterFrameCtxt *ctxt = (FilterFrameCtxt *)priv;
   const RestorationInfo *rsi = ctxt->rsi;
 
@@ -1588,6 +1600,9 @@
 #if CONFIG_EXT_LOOP_RESTORATION
     RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+    Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
     RestorationLineBuffers *rlbs, sync_read_fn_t on_sync_read,
     sync_write_fn_t on_sync_write, struct AV1LrSyncData *const lr_sync) {
   const int tile_w = tile_rect->right - tile_rect->left;
@@ -1614,9 +1629,12 @@
       on_sync_read(lr_sync, row_number + 2, j, plane);
 #if CONFIG_EXT_LOOP_RESTORATION
     on_rest_unit(limits, tile_rect, unit_idx, priv, tmpbuf, previous_rui, rlbs);
+#elif CONFIG_RST_MERGECOEFFS
+    on_rest_unit(limits, tile_rect, unit_idx, priv, tmpbuf, current_unit_stack,
+                 rlbs);
 #else
     on_rest_unit(limits, tile_rect, unit_idx, priv, tmpbuf, rlbs);
-#endif  // CONFIG_EXT_LOOP_RESTORATION
+#endif  // CONFIG_EXT_LOOP_RESTORATION, CONFIG_RST_MERGECOEFFS
 
     on_sync_write(lr_sync, row_number, j, hunits_per_tile, plane);
 
@@ -1651,6 +1669,9 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                                       RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                                      Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                                       RestorationLineBuffers *rlbs) {
   const int tile_h = tile_rect->bottom - tile_rect->top;
   const int ext_size = unit_size * 3 / 2;
@@ -1676,12 +1697,18 @@
         &limits, tile_rect, on_rest_unit, i, unit_size, unit_idx0,
         hunits_per_tile, vunits_per_tile, plane, priv, tmpbuf, previous_rui,
         rlbs, av1_lr_sync_read_dummy, av1_lr_sync_write_dummy, NULL);
+#elif CONFIG_RST_MERGECOEFFS
+    av1_foreach_rest_unit_in_row(&limits, tile_rect, on_rest_unit, i, unit_size,
+                                 unit_idx0, hunits_per_tile, vunits_per_tile,
+                                 plane, priv, tmpbuf, current_unit_stack, rlbs,
+                                 av1_lr_sync_read_dummy,
+                                 av1_lr_sync_write_dummy, NULL);
 #else
     av1_foreach_rest_unit_in_row(
         &limits, tile_rect, on_rest_unit, i, unit_size, unit_idx0,
         hunits_per_tile, vunits_per_tile, plane, priv, tmpbuf, rlbs,
         av1_lr_sync_read_dummy, av1_lr_sync_write_dummy, NULL);
-#endif  // CONFIG_EXT_LOOP_RESTORATION
+#endif  // CONFIG_EXT_LOOP_RESTORATION, CONFIG_RST_MERGECOEFFS
 
     y0 += h;
     ++i;
@@ -1706,12 +1733,24 @@
                             rsi->units_per_tile, rsi->restoration_unit_size,
                             ss_y, plane, on_rest_unit, priv, tmpbuf, &param_buf,
                             rlbs);
+#elif CONFIG_RST_MERGECOEFFS
+  // this vector holds the most recent list of units with merged coefficients
+  Vector current_unit_stack;
+  memset(&current_unit_stack, 0, sizeof(Vector));
+  // no object to use for setup exists, so we can use size of an existing
+  // pointer value
+  aom_vector_setup(&current_unit_stack, 1, sizeof(&current_unit_stack));
+  foreach_rest_unit_in_tile(tile_rect, LR_TILE_ROW, LR_TILE_COL, LR_TILE_COLS,
+                            rsi->horz_units_per_tile, rsi->vert_units_per_tile,
+                            rsi->units_per_tile, rsi->restoration_unit_size,
+                            ss_y, plane, on_rest_unit, priv, tmpbuf,
+                            &current_unit_stack, rlbs);
 #else
   foreach_rest_unit_in_tile(tile_rect, LR_TILE_ROW, LR_TILE_COL, LR_TILE_COLS,
                             rsi->horz_units_per_tile, rsi->vert_units_per_tile,
                             rsi->units_per_tile, rsi->restoration_unit_size,
                             ss_y, plane, on_rest_unit, priv, tmpbuf, rlbs);
-#endif  // CONFIG_EXT_LOOP_RESTORATION
+#endif  // CONFIG_EXT_LOOP_RESTORATION, CONFIG_RST_MERGECOEFFS
 }
 
 int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane,
diff --git a/av1/common/restoration.h b/av1/common/restoration.h
index 3bd4bba..24bce17 100644
--- a/av1/common/restoration.h
+++ b/av1/common/restoration.h
@@ -18,6 +18,10 @@
 #include "av1/common/blockd.h"
 #include "av1/common/enums.h"
 
+#if CONFIG_RST_MERGECOEFFS
+#include "third_party/vector/vector.h"
+#endif  // CONFIG_RST_MERGECOEFFS
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -394,6 +398,9 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                                     RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                                    Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                                     RestorationLineBuffers *rlbs);
 
 typedef struct FilterFrameCtxt {
@@ -519,6 +526,9 @@
 #if CONFIG_EXT_LOOP_RESTORATION
     RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+    Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
     RestorationLineBuffers *rlbs, sync_read_fn_t on_sync_read,
     sync_write_fn_t on_sync_write, struct AV1LrSyncData *const lr_sync);
 AV1PixelRect av1_whole_frame_rect(const struct AV1Common *cm, int is_uv);
diff --git a/av1/common/thread_common.c b/av1/common/thread_common.c
index a115d18..2843b8cd 100644
--- a/av1/common/thread_common.c
+++ b/av1/common/thread_common.c
@@ -575,6 +575,7 @@
 #endif  // CONFIG_MULTITHREAD
 }
 
+#if !CONFIG_RST_MERGECOEFFS
 // Allocate memory for loop restoration row synchronization
 static void loop_restoration_alloc(AV1LrSync *lr_sync, AV1_COMMON *cm,
                                    int num_workers, int num_rows_lr,
@@ -639,6 +640,7 @@
   // Set up nsync.
   lr_sync->sync_range = get_lr_sync_range(width);
 }
+#endif  // !CONFIG_RST_MERGECOEFFS
 
 // Deallocate loop restoration synchronization related mutex and data
 void av1_loop_restoration_dealloc(AV1LrSync *lr_sync, int num_workers) {
@@ -688,6 +690,7 @@
   }
 }
 
+#if !CONFIG_RST_MERGECOEFFS
 static void enqueue_lr_jobs(AV1LrSync *lr_sync, AV1LrStruct *lr_ctxt,
                             AV1_COMMON *cm) {
   FilterFrameCtxt *ctxt = lr_ctxt->ctxt;
@@ -784,8 +787,10 @@
 
   return cur_job_info;
 }
+#endif  // !CONFIG_RST_MERGECOEFFS
 
-#if !CONFIG_EXT_LOOP_RESTORATION || !CONFIG_RST_MERGECOEFFS
+#if !CONFIG_RST_MERGECOEFFS
+#if !CONFIG_EXT_LOOP_RESTORATION
 // Implement row loop restoration for each thread.
 static int loop_restoration_row_worker(void *arg1, void *arg2) {
   AV1LrSync *const lr_sync = (AV1LrSync *)arg1;
@@ -921,4 +926,5 @@
   foreach_rest_unit_in_planes_mt(loop_rest_ctxt, workers, num_workers, lr_sync,
                                  cm);
 }
-#endif  // !CONFIG_EXT_LOOP_RESTORATION || !CONFIG_RST_MERGECOEFFS
+#endif  // !CONFIG_EXT_LOOP_RESTORATION
+#endif  // !CONFIG_RST_MERGECOEFFS
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 731c69b..5aec91e 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -37,6 +37,10 @@
 #include "av1/encoder/pickrst.h"
 #include "av1/encoder/rdopt.h"
 
+#if CONFIG_RST_MERGECOEFFS
+#include "third_party/vector/vector.h"
+#endif  // CONFIG_RST_MERGECOEFFS
+
 // When set to RESTORE_WIENER or RESTORE_SGRPROJ only those are allowed.
 // When set to RESTORE_TYPES we allow switchable.
 #if CONFIG_RST_MERGECOEFFS
@@ -721,7 +725,14 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                            RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                           Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                            RestorationLineBuffers *rlbs) {
+#if CONFIG_RST_MERGECOEFFS
+  // required in function signature but not needed in this function
+  (void)current_unit_stack;
+#endif  // CONFIG_RST_MERGECOEFFS
   (void)rlbs;
   RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
   RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
@@ -1065,6 +1076,7 @@
   return 1;
 }
 
+#if !CONFIG_RST_MERGECOEFFS
 // Computes the function x'*H*x - x'*M for the learned 2D filter x, and compares
 // against identity filters; Final score is defined as the difference between
 // the function values
@@ -1108,6 +1120,7 @@
 
   return Score - iScore;
 }
+#endif  // !CONFIG_RST_MERGECOEFFS
 
 static void finalize_sym_filter(int wiener_win, int32_t *f, InterpKernel fi) {
   int i;
@@ -1299,8 +1312,15 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                           RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                          Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                           RestorationLineBuffers *rlbs) {
   (void)tmpbuf;
+#if CONFIG_RST_MERGECOEFFS
+  // required in function signature but not needed in this function
+  (void)current_unit_stack;
+#endif  // CONFIG_RST_MERGECOEFFS
   (void)rlbs;
   RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
   RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];
@@ -1350,7 +1370,8 @@
   finalize_sym_filter(reduced_wiener_win, vfilter, rui.wiener_info.vfilter);
   finalize_sym_filter(reduced_wiener_win, hfilter, rui.wiener_info.hfilter);
 
-#if !CONFIG_EXT_LOOP_RESTORATION || !CONFIG_RST_MERGECOEFFS
+#if !CONFIG_RST_MERGECOEFFS
+#if !CONFIG_EXT_LOOP_RESTORATION
   // Disabled for experiment because it doesn't factor reduced bit count
   // into calculations.
   // Filter score computes the value of the function x'*A*x - x'*b for the
@@ -1364,7 +1385,8 @@
     rusi->sse[RESTORE_WIENER] = INT64_MAX;
     return;
   }
-#endif  // !CONFIG_EXT_LOOP_RESTORATION || CONFIG_RST_MERGECOEFFS
+#endif  // !CONFIG_EXT_LOOP_RESTORATION
+#endif  // !CONFIG_RST_MERGECOEFFS
 
   aom_clear_system_state();
 
@@ -1447,9 +1469,16 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                              RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                             Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                              RestorationLineBuffers *rlbs) {
   (void)tile_rect;
   (void)tmpbuf;
+#if CONFIG_RST_MERGECOEFFS
+  // required in function signature but not needed in this function
+  (void)current_unit_stack;
+#endif  // CONFIG_RST_MERGECOEFFS
   (void)rlbs;
 
   RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
@@ -1775,10 +1804,17 @@
 #if CONFIG_EXT_LOOP_RESTORATION
                               RestorationUnitInfo *previous_rui,
 #endif  // CONFIG_EXT_LOOP_RESTORATION
+#if CONFIG_RST_MERGECOEFFS
+                              Vector *current_unit_stack,
+#endif  // CONFIG_RST_MERGECOEFFS
                               RestorationLineBuffers *rlbs) {
   (void)limits;
   (void)tile_rect;
   (void)tmpbuf;
+#if CONFIG_RST_MERGECOEFFS
+  // required in function signature but not needed in this function
+  (void)current_unit_stack;
+#endif  // CONFIG_RST_MERGECOEFFS
   (void)rlbs;
   RestSearchCtxt *rsc = (RestSearchCtxt *)priv;
   RestUnitSearchInfo *rusi = &rsc->rusi[rest_unit_idx];