Refactor av1_update_neighbors

Beside above and left positions, additional above-left,
above-right, and bottom-left positions are added as
neighbor candidates.

In av1_update_neighbors, two available positions will be picked as
context neighbors.

The picking priority is
above -> left -> above-left -> above->right -> bottom->left

Change-Id: I82eaf0b23d0189caaea008ecc86776492886a05b
diff --git a/av1/common/scan.c b/av1/common/scan.c
index bf161ab..b5cde7c 100644
--- a/av1/common/scan.c
+++ b/av1/common/scan.c
@@ -6500,19 +6500,32 @@
     const int coeff_idx = scan[scan_idx];
     const int r = coeff_idx / tx1d_size;
     const int c = coeff_idx % tx1d_size;
-    const int has_left = c > 0 && iscan[coeff_idx - 1] < scan_idx;
-    const int has_above = r > 0 && iscan[coeff_idx - tx1d_size] < scan_idx;
+    const int nb_offset_r[5] = { -1, 0, -1, -1, 1 };
+    const int nb_offset_c[5] = { 0, -1, -1, 1, -1 };
+    const int nb_num = 5;
+    int nb_count = 0;
+    int nb_idx;
 
-    if (has_left && has_above) {
-      neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
-      neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
-    } else if (has_left) {
-      neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
-      neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - 1;
-    } else if (has_above) {
-      neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - tx1d_size;
-      neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
-    } else {
+    for (nb_idx = 0; nb_idx < nb_num; ++nb_idx) {
+      if (nb_count < 2) {
+        int nb_r = r + nb_offset_r[nb_idx];
+        int nb_c = c + nb_offset_c[nb_idx];
+        int nb_coeff_idx = nb_r * tx1d_size + nb_c;
+        int valid_pos =
+            nb_r >= 0 && nb_r < tx1d_size && nb_c >= 0 && nb_c < tx1d_size;
+        if (valid_pos && iscan[nb_coeff_idx] < scan_idx) {
+          neighbors[scan_idx * MAX_NEIGHBORS + nb_count] = nb_coeff_idx;
+          ++nb_count;
+        }
+      } else {
+        break;
+      }
+    }
+
+    if (nb_count == 1) {
+      neighbors[scan_idx * MAX_NEIGHBORS + 1] =
+          neighbors[scan_idx * MAX_NEIGHBORS + 0];
+    } else if (nb_count == 0) {
       neighbors[scan_idx * MAX_NEIGHBORS + 0] = scan[0];
       neighbors[scan_idx * MAX_NEIGHBORS + 1] = scan[0];
     }
diff --git a/test/scan_test.cc b/test/scan_test.cc
index 6c7fecf..5724883 100644
--- a/test/scan_test.cc
+++ b/test/scan_test.cc
@@ -81,13 +81,14 @@
   const int16_t scan[16] = { 0, 1, 2,  3,  4,  5,  6,  7,
                              8, 9, 10, 11, 12, 13, 14, 15 };
   int16_t nb[(16 + 1) * 2];
-  const int16_t ref_nb[(16 + 1) * 2] = { 0, 0,  0,  0,  1,  1, 2, 2, 0,
-                                         0, 4,  1,  5,  2,  6, 3, 4, 4,
-                                         8, 5,  9,  6,  10, 7, 8, 8, 12,
-                                         9, 13, 10, 14, 11, 0, 0 };
+  const int16_t ref_nb[(16 + 1) * 2] = { 0,  0,  0,  0,  1,  1,  2, 2, 0,
+                                         1,  1,  4,  2,  5,  3,  6, 4, 5,
+                                         5,  8,  6,  9,  7,  10, 8, 9, 9,
+                                         12, 10, 13, 11, 14, 0,  0 };
 
   // raster order's scan and iscan are the same
   av1_update_neighbors(tx_size, scan, scan, nb);
+
   for (int i = 0; i < (16 + 1) * 2; ++i) {
     EXPECT_EQ(ref_nb[i], nb[i]);
   }