Refactor `temporal_filter.c`.

Refactor Step-1: Function to build predictors.

After refactoring, the function will handle different planes and
sub-blocks uniformly.

Change-Id: I7f80100da321c9bda7b414a38bdd72a72daf59d8
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index ae94c91..24de6db 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -36,126 +36,139 @@
 #include "aom_ports/system_state.h"
 #include "aom_scale/aom_scale.h"
 
-static unsigned int index_mult[14] = { 0,     0,     0,     0,     49152,
-                                       39322, 32768, 28087, 24576, 21846,
-                                       19661, 17874, 0,     15124 };
+// NOTE: All `tf` in this file means `temporal filtering`.
 
-static int64_t highbd_index_mult[14] = { 0U,          0U,          0U,
-                                         0U,          3221225472U, 2576980378U,
-                                         2147483648U, 1840700270U, 1610612736U,
-                                         1431655766U, 1288490189U, 1171354718U,
-                                         0U,          991146300U };
+// Magic numbers used to compute pixel-wise averaging weights for filtering.
+// Only supports 3x3 window for filtering, hence, there are totally 9 non-zero
+// numbers within the 14-element multiplier lookup table. 5 zeros should never
+// be visited.
+static const unsigned int index_mult[14] = { 0,     0,     0,     0,     49152,
+                                             39322, 32768, 28087, 24576, 21846,
+                                             19661, 17874, 0,     15124 };
+// Magic numbers (for high bit-depth).
+static const int64_t highbd_index_mult[14] = {
+  0U,          0U,          0U,          0U,          3221225472U,
+  2576980378U, 2147483648U, 1840700270U, 1610612736U, 1431655766U,
+  1288490189U, 1171354718U, 0U,          991146300U
+};
 
-static void temporal_filter_predictors_mb_c(YV12_BUFFER_CONFIG *ref_frame,
-                                            MACROBLOCKD *xd, int uv_block_width,
-                                            int uv_block_height, int mv_row,
-                                            int mv_col, uint8_t *pred,
-                                            struct scale_factors *scale, int x,
-                                            int y, int num_planes, MV *blk_mvs,
-                                            int use_32x32) {
+static INLINE int mod_index(int sum_dist, int index, int rounding, int strength,
+                            int filter_weight) {
+  assert(index >= 0 && index <= 13);
+  assert(index_mult[index] != 0);
+
+  int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16;
+  mod += rounding;
+  mod >>= strength;
+
+  mod = AOMMIN(16, mod);
+
+  mod = 16 - mod;
+  mod *= filter_weight;
+
+  return mod;
+}
+
+static INLINE int highbd_mod_index(int64_t sum_dist, int index, int rounding,
+                                   int strength, int filter_weight) {
+  assert(index >= 0 && index <= 13);
+  assert(highbd_index_mult[index] != 0);
+
+  int mod =
+      (int)((AOMMIN(sum_dist, INT32_MAX) * highbd_index_mult[index]) >> 32);
+  mod += rounding;
+  mod >>= strength;
+
+  mod = AOMMIN(16, mod);
+
+  mod = 16 - mod;
+  mod *= filter_weight;
+
+  return mod;
+}
+
+// Builds predictors for blocks in temporal filtering.
+// Inputs:
+//   ref_frame: Pointer to the frame for filtering.
+//   mbd: Pointer to the block for filtering.
+//   block_size: Size of the block.
+//   mb_row: Row index of the block in the entire frame.
+//   mb_col: Column index of the block in the entire frame.
+//   scale: Scaling factor.
+//   num_planes: Number of planes in the frame.
+//   use_subblock: Whether to use four sub-blocks to replace the original block.
+//   subblock_mvs: The motion vectors for each sub-blocks. (row-major order).
+//   pred: Pointer to the predictors to build.
+// Returns:
+//   Nothing will be returned. But the content to which `pred` points will be
+//   modified.
+static void tf_build_predictors_mb_c(
+    const YV12_BUFFER_CONFIG *ref_frame, const MACROBLOCKD *mbd,
+    const BLOCK_SIZE block_size, const int mb_row, const int mb_col,
+    const struct scale_factors *scale, const int num_planes,
+    const int use_subblock, const MV *subblock_mvs, uint8_t *pred) {
+  // Information of the entire block.
+  const int mb_height = block_size_high[block_size];  // Height.
+  const int mb_width = block_size_wide[block_size];   // Width.
+  const int mb_size = mb_height * mb_width;           // Number of pixels.
+  const int mb_y = mb_height * mb_row;                // Y-coord.
+  const int mb_x = mb_width * mb_col;                 // X-coord.
+  const int bit_depth = mbd->bd;                      // Bit depth.
+  const int is_high_bitdepth = is_cur_buf_hbd(mbd);   // Is high bit-depth?
+  const int is_intrabc = 0;                           // Is intra-copied?
+  const int mb_mv_row = mbd->mi[0]->mv[0].as_mv.row;  // Motion vector (y).
+  const int mb_mv_col = mbd->mi[0]->mv[0].as_mv.col;  // Motion vector (x).
+  const MV mb_mv = { (int16_t)mb_mv_row, (int16_t)mb_mv_col };
+
+  // Information of each sub-block (actually in use).
+  const int num_blocks = use_subblock ? 2 : 1;  // Num of blocks on each side.
+  const int block_height = mb_height >> (num_blocks - 1);  // Height.
+  const int block_width = mb_width >> (num_blocks - 1);    // Width.
+
+  // Default interpolation filters.
   const int_interpfilters interp_filters =
       av1_broadcast_interp_filter(MULTITAP_SHARP);
-  WarpTypesAllowed warp_types;
-  memset(&warp_types, 0, sizeof(WarpTypesAllowed));
 
   InterPredParams inter_pred_params;
-  struct buf_2d ref_buf_y = { NULL, ref_frame->y_buffer, ref_frame->y_width,
-                              ref_frame->y_height, ref_frame->y_stride };
+  struct buf_2d ref_buf = { NULL, NULL, 0, 0, 0 };
 
-  av1_init_inter_params(&inter_pred_params, BW, BH, y, x, 0, 0, xd->bd,
-                        is_cur_buf_hbd(xd), 0, scale, &ref_buf_y,
-                        interp_filters);
-  inter_pred_params.conv_params = get_conv_params(0, 0, xd->bd);
-
-  if (use_32x32) {
-    assert(mv_row >= INT16_MIN && mv_row <= INT16_MAX && mv_col >= INT16_MIN &&
-           mv_col <= INT16_MAX);
-    const MV mv = { (int16_t)mv_row, (int16_t)mv_col };
-
-    av1_build_inter_predictor(&pred[0], BW, &mv, &inter_pred_params);
-
-    if (num_planes > 1) {
-      struct buf_2d ref_buf_uv = { NULL, ref_frame->u_buffer,
-                                   ref_frame->uv_width, ref_frame->uv_height,
-                                   ref_frame->uv_stride };
-
-      av1_init_inter_params(
-          &inter_pred_params, uv_block_width, uv_block_height,
-          y >> xd->plane[1].subsampling_y, x >> xd->plane[1].subsampling_x,
-          xd->plane[1].subsampling_x, xd->plane[1].subsampling_y, xd->bd,
-          is_cur_buf_hbd(xd), 0, scale, &ref_buf_uv, interp_filters);
-      inter_pred_params.conv_params = get_conv_params(0, 1, xd->bd);
-      av1_build_inter_predictor(&pred[BLK_PELS], uv_block_width, &mv,
-                                &inter_pred_params);
-
-      ref_buf_uv.buf0 = ref_frame->v_buffer;
-      av1_init_inter_params(
-          &inter_pred_params, uv_block_width, uv_block_height,
-          y >> xd->plane[1].subsampling_y, x >> xd->plane[1].subsampling_x,
-          xd->plane[1].subsampling_x, xd->plane[1].subsampling_y, xd->bd,
-          is_cur_buf_hbd(xd), 0, scale, &ref_buf_uv, interp_filters);
-      inter_pred_params.conv_params = get_conv_params(0, 2, xd->bd);
-      av1_build_inter_predictor(&pred[(BLK_PELS << 1)], uv_block_width, &mv,
-                                &inter_pred_params);
+  // Handle Y-plane and UV-plane.
+  for (int plane = 0; plane < num_planes; ++plane) {
+    const int subsampling_y = mbd->plane[plane].subsampling_y;
+    const int subsampling_x = mbd->plane[plane].subsampling_x;
+    const int plane_y = mb_y >> subsampling_y;
+    const int plane_x = mb_x >> subsampling_x;
+    const int h = block_height >> subsampling_y;
+    const int w = block_width >> subsampling_x;
+    const int pred_stride = mb_width >> subsampling_x;
+    switch (plane) {
+      case 0: ref_buf.buf0 = ref_frame->y_buffer; break;
+      case 1: ref_buf.buf0 = ref_frame->u_buffer; break;
+      case 2: ref_buf.buf0 = ref_frame->v_buffer; break;
+      default: assert(0 && "Number of planes should be at most 3.");
     }
+    ref_buf.height = (plane == 0) ? ref_frame->y_height : ref_frame->uv_height;
+    ref_buf.width = (plane == 0) ? ref_frame->y_width : ref_frame->uv_width;
+    ref_buf.stride = (plane == 0) ? ref_frame->y_stride : ref_frame->uv_stride;
 
-    return;
-  }
+    // Handle entire block or sub-blocks if needed.
+    for (int i = 0; i < num_blocks; ++i) {
+      for (int j = 0; j < num_blocks; ++j) {
+        // Choose proper motion vector.
+        const MV mv = use_subblock ? subblock_mvs[i * num_blocks + j] : mb_mv;
+        assert(mv.row >= INT16_MIN && mv.row <= INT16_MAX &&
+               mv.col >= INT16_MIN && mv.col <= INT16_MAX);
 
-  // While use_32x32 = 0, construct the 32x32 predictor using 4 16x16
-  // predictors.
-  int i, j, k = 0, ys = (BH >> 1), xs = (BW >> 1);
-  // Y predictor
-  for (i = 0; i < BH; i += ys) {
-    for (j = 0; j < BW; j += xs) {
-      const MV mv = blk_mvs[k];
-      const int p_offset = i * BW + j;
+        const int y = plane_y + i * h;
+        const int x = plane_x + j * w;
 
-      av1_init_inter_params(&inter_pred_params, xs, ys, y + i, x + j, 0, 0,
-                            xd->bd, is_cur_buf_hbd(xd), 0, scale, &ref_buf_y,
-                            interp_filters);
-      inter_pred_params.conv_params = get_conv_params(0, 0, xd->bd);
-
-      av1_build_inter_predictor(&pred[p_offset], BW, &mv, &inter_pred_params);
-      k++;
-    }
-  }
-
-  // U and V predictors
-  if (num_planes > 1) {
-    ys = (uv_block_height >> 1);
-    xs = (uv_block_width >> 1);
-    k = 0;
-
-    for (i = 0; i < uv_block_height; i += ys) {
-      for (j = 0; j < uv_block_width; j += xs) {
-        const MV mv = blk_mvs[k];
-        const int p_offset = i * uv_block_width + j;
-
-        struct buf_2d ref_buf_uv = { NULL, ref_frame->u_buffer,
-                                     ref_frame->uv_width, ref_frame->uv_height,
-                                     ref_frame->uv_stride };
-
-        av1_init_inter_params(
-            &inter_pred_params, xs, ys, (y >> xd->plane[1].subsampling_y) + i,
-            (x >> xd->plane[1].subsampling_x) + j, xd->plane[1].subsampling_x,
-            xd->plane[1].subsampling_y, xd->bd, is_cur_buf_hbd(xd), 0, scale,
-            &ref_buf_uv, interp_filters);
-        inter_pred_params.conv_params = get_conv_params(0, 1, xd->bd);
-        av1_build_inter_predictor(&pred[BLK_PELS + p_offset], uv_block_width,
+        const int offset = i * h * pred_stride + j * w;
+        av1_init_inter_params(&inter_pred_params, w, h, y, x, subsampling_x,
+                              subsampling_y, bit_depth, is_high_bitdepth,
+                              is_intrabc, scale, &ref_buf, interp_filters);
+        inter_pred_params.conv_params = get_conv_params(0, plane, bit_depth);
+        av1_build_inter_predictor(&pred[mb_size * plane + offset], pred_stride,
                                   &mv, &inter_pred_params);
-
-        ref_buf_uv.buf0 = ref_frame->v_buffer;
-        av1_init_inter_params(
-            &inter_pred_params, xs, ys, (y >> xd->plane[1].subsampling_y) + i,
-            (x >> xd->plane[1].subsampling_x) + j, xd->plane[1].subsampling_x,
-            xd->plane[1].subsampling_y, xd->bd, is_cur_buf_hbd(xd), 0, scale,
-            &ref_buf_uv, interp_filters);
-
-        inter_pred_params.conv_params = get_conv_params(0, 2, xd->bd);
-        av1_build_inter_predictor(&pred[(BLK_PELS << 1) + p_offset],
-                                  uv_block_width, &mv, &inter_pred_params);
-        k++;
       }
     }
   }
@@ -198,41 +211,6 @@
   }
 }
 
-static INLINE int mod_index(int sum_dist, int index, int rounding, int strength,
-                            int filter_weight) {
-  assert(index >= 0 && index <= 13);
-  assert(index_mult[index] != 0);
-
-  int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16;
-  mod += rounding;
-  mod >>= strength;
-
-  mod = AOMMIN(16, mod);
-
-  mod = 16 - mod;
-  mod *= filter_weight;
-
-  return mod;
-}
-
-static INLINE int highbd_mod_index(int64_t sum_dist, int index, int rounding,
-                                   int strength, int filter_weight) {
-  assert(index >= 0 && index <= 13);
-  assert(highbd_index_mult[index] != 0);
-
-  int mod =
-      (int)((AOMMIN(sum_dist, INT32_MAX) * highbd_index_mult[index]) >> 32);
-  mod += rounding;
-  mod >>= strength;
-
-  mod = AOMMIN(16, mod);
-
-  mod = 16 - mod;
-  mod *= filter_weight;
-
-  return mod;
-}
-
 static INLINE void calculate_squared_errors(const uint8_t *s, int s_stride,
                                             const uint8_t *p, int p_stride,
                                             uint16_t *diff_sse, unsigned int w,
@@ -1165,11 +1143,9 @@
 
         if (blk_fw[0] || blk_fw[1] || blk_fw[2] || blk_fw[3]) {
           // Construct the predictors
-          temporal_filter_predictors_mb_c(
-              frames[frame], mbd, mb_uv_width, mb_uv_height,
-              mbd->mi[0]->mv[0].as_mv.row, mbd->mi[0]->mv[0].as_mv.col,
-              predictor, ref_scale_factors, mb_col * BW, mb_row * BH,
-              num_planes, blk_mvs, use_32x32);
+          tf_build_predictors_mb_c(frames[frame], mbd, TF_BLOCK, mb_row, mb_col,
+                                   ref_scale_factors, num_planes, !(use_32x32),
+                                   blk_mvs, predictor);
 
           // Apply the filter (YUV)
           if (frame == alt_ref_index) {