Use default scan order as a tie breaker

Change-Id: I85f059b6e2c48bcdf2edd3b7bf896fdccbaaa703
diff --git a/av1/common/scan.c b/av1/common/scan.c
index 0376b82..bf161ab 100644
--- a/av1/common/scan.c
+++ b/av1/common/scan.c
@@ -6458,15 +6458,17 @@
   return *(const uint32_t *)b > *(const uint32_t *)a ? 1 : -1;
 }
 
-void av1_augment_prob(uint32_t *prob, int size, int tx1d_size) {
+void av1_augment_prob(TX_SIZE tx_size, TX_TYPE tx_type, uint32_t *prob) {
+  // TODO(angiebird): check if we need is_inter here
+  const SCAN_ORDER *sc = get_default_scan(tx_size, tx_type, 0);
+  const int tx1d_size = tx_size_wide[tx_size];
   int r, c;
-  for (r = 0; r < size; r++) {
-    for (c = 0; c < size; c++) {
-      const int coeff_idx = r * tx1d_size + c;
-      const int idx = r * size + c;
+  for (r = 0; r < tx1d_size; r++) {
+    for (c = 0; c < tx1d_size; c++) {
+      const int idx = r * tx1d_size + c;
       const uint32_t mask_16 = ((1 << 16) - 1);
-      const uint32_t tie_breaker = ~(((r + c) << COEFF_IDX_BITS) | coeff_idx);
-      // prob[idx]: 16 bits  r+c: 6 bits  coeff_idx: 10 bits
+      const uint32_t tie_breaker = ~((uint32_t)sc->iscan[idx]);
+      // prob[idx]: 16 bits  dummy: 6 bits  scan_idx: 10 bits
       prob[idx] = (prob[idx] << 16) | (mask_16 & tie_breaker);
     }
   }
@@ -6519,18 +6521,20 @@
   neighbors[tx2d_size * MAX_NEIGHBORS + 1] = scan[0];
 }
 
-void av1_update_sort_order(TX_SIZE tx_size, const uint32_t *non_zero_prob,
-                           int16_t *sort_order) {
+void av1_update_sort_order(TX_SIZE tx_size, TX_TYPE tx_type,
+                           const uint32_t *non_zero_prob, int16_t *sort_order) {
+  const SCAN_ORDER *sc = get_default_scan(tx_size, tx_type, 0);
   uint32_t temp[COEFF_IDX_SIZE];
-  const int tx1d_size = tx_size_wide[tx_size];
   const int tx2d_size = tx_size_2d[tx_size];
   int sort_idx;
   assert(tx2d_size <= COEFF_IDX_SIZE);
   memcpy(temp, non_zero_prob, tx2d_size * sizeof(*non_zero_prob));
-  av1_augment_prob(temp, tx1d_size, tx1d_size);
+  av1_augment_prob(tx_size, tx_type, temp);
   qsort(temp, tx2d_size, sizeof(*temp), cmp_prob);
   for (sort_idx = 0; sort_idx < tx2d_size; ++sort_idx) {
-    const int coeff_idx = (temp[sort_idx] & COEFF_IDX_MASK) ^ COEFF_IDX_MASK;
+    const int default_scan_idx =
+        (temp[sort_idx] & COEFF_IDX_MASK) ^ COEFF_IDX_MASK;
+    const int coeff_idx = sc->scan[default_scan_idx];
     sort_order[sort_idx] = coeff_idx;
   }
 }
@@ -6562,7 +6566,7 @@
   int16_t *iscan = get_adapt_iscan(cm->fc, tx_size, tx_type);
   int16_t *nb = get_adapt_nb(cm->fc, tx_size, tx_type);
   assert(tx_size_2d[tx_size] <= COEFF_IDX_SIZE);
-  av1_update_sort_order(tx_size, non_zero_prob, sort_order);
+  av1_update_sort_order(tx_size, tx_type, non_zero_prob, sort_order);
   av1_update_scan_order(tx_size, sort_order, scan, iscan);
   av1_update_neighbors(tx_size, scan, iscan, nb);
 }
diff --git a/av1/common/scan.h b/av1/common/scan.h
index 01f37b6..71868d0 100644
--- a/av1/common/scan.h
+++ b/av1/common/scan.h
@@ -39,11 +39,11 @@
 // embed r + c and coeff_idx info with nonzero probabilities. When sorting the
 // nonzero probabilities, if there is a tie, the coefficient with smaller r + c
 // will be scanned first
-void av1_augment_prob(uint32_t *prob, int size, int tx1d_size);
+void av1_augment_prob(TX_SIZE tx_size, TX_TYPE tx_type, uint32_t *prob);
 
 // apply quick sort on nonzero probabilities to obtain a sort order
-void av1_update_sort_order(TX_SIZE tx_size, const uint32_t *non_zero_prob,
-                           int16_t *sort_order);
+void av1_update_sort_order(TX_SIZE tx_size, TX_TYPE tx_type,
+                           const uint32_t *non_zero_prob, int16_t *sort_order);
 
 // apply topological sort on the nonzero probabilities sorting order to
 // guarantee each to-be-scanned coefficient's upper and left coefficient will be
@@ -67,13 +67,9 @@
          1;
 }
 
-static INLINE const SCAN_ORDER *get_scan(const AV1_COMMON *cm, TX_SIZE tx_size,
-                                         TX_TYPE tx_type, int is_inter) {
-#if CONFIG_ADAPT_SCAN
-  (void)is_inter;
-  return &cm->fc->sc[tx_size][tx_type];
-#else  // CONFIG_ADAPT_SCAN
-  (void)cm;
+static INLINE const SCAN_ORDER *get_default_scan(TX_SIZE tx_size,
+                                                 TX_TYPE tx_type,
+                                                 int is_inter) {
 #if CONFIG_EXT_TX || CONFIG_VAR_TX
   return is_inter ? &av1_inter_scan_orders[tx_size][tx_type]
                   : &av1_intra_scan_orders[tx_size][tx_type];
@@ -81,6 +77,16 @@
   (void)is_inter;
   return &av1_intra_scan_orders[tx_size][tx_type];
 #endif  // CONFIG_EXT_TX
+}
+
+static INLINE const SCAN_ORDER *get_scan(const AV1_COMMON *cm, TX_SIZE tx_size,
+                                         TX_TYPE tx_type, int is_inter) {
+#if CONFIG_ADAPT_SCAN
+  (void)is_inter;
+  return &cm->fc->sc[tx_size][tx_type];
+#else   // CONFIG_ADAPT_SCAN
+  (void)cm;
+  return get_default_scan(tx_size, tx_type, is_inter);
 #endif  // CONFIG_ADAPT_SCAN
 }
 
diff --git a/test/scan_test.cc b/test/scan_test.cc
index ec2219c..6c7fecf 100644
--- a/test/scan_test.cc
+++ b/test/scan_test.cc
@@ -9,18 +9,21 @@
  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
  */
 
+#include "av1/common/common_data.h"
 #include "av1/common/scan.h"
 #include "third_party/googletest/src/include/gtest/gtest.h"
 
 namespace {
 
 TEST(ScanTest, av1_augment_prob) {
-  const int tx1d_size = 4;
+  const TX_SIZE tx_size = TX_4X4;
+  const TX_TYPE tx_type = DCT_DCT;
+  const int tx1d_size = tx_size_wide[tx_size];
   uint32_t prob[16] = { 8, 8, 7, 7, 8, 8, 4, 2, 3, 3, 2, 2, 2, 2, 2, 2 };
   const uint32_t ref_prob[16] = {
     8, 8, 7, 7, 8, 8, 4, 2, 3, 3, 2, 2, 2, 2, 2, 2
   };
-  av1_augment_prob(prob, tx1d_size, tx1d_size);
+  av1_augment_prob(tx_size, tx_type, prob);
   for (int r = 0; r < tx1d_size; ++r) {
     for (int c = 0; c < tx1d_size; ++c) {
       const uint32_t idx = r * tx1d_size + c;
@@ -28,35 +31,42 @@
     }
   }
 
-  const uint32_t mask = (1 << 10) - 1;
+  const SCAN_ORDER *sc = get_default_scan(tx_size, tx_type, 0);
+  const uint32_t mask = (1 << 16) - 1;
   for (int r = 0; r < tx1d_size; ++r) {
     for (int c = 0; c < tx1d_size; ++c) {
-      const uint32_t idx = r * tx1d_size + c;
-      EXPECT_EQ(idx, mask ^ (prob[r * tx1d_size + c] & mask));
+      const uint32_t ref_idx = r * tx1d_size + c;
+      const uint32_t scan_idx = mask ^ (prob[r * tx1d_size + c] & mask);
+      const uint32_t idx = sc->scan[scan_idx];
+      EXPECT_EQ(ref_idx, idx);
     }
   }
 }
 
 TEST(ScanTest, av1_update_sort_order) {
   const TX_SIZE tx_size = TX_4X4;
-  const uint32_t prob[16] = { 8, 8, 7, 7, 8, 8, 4, 2, 3, 3, 2, 2, 2, 2, 2, 2 };
+  const TX_TYPE tx_type = DCT_DCT;
+  const uint32_t prob[16] = { 15, 14, 11, 10, 13, 12, 9, 5,
+                              8,  7,  4,  2,  6,  3,  1, 0 };
   const int16_t ref_sort_order[16] = { 0, 1,  4, 5,  2,  3,  6,  8,
                                        9, 12, 7, 10, 13, 11, 14, 15 };
   int16_t sort_order[16];
-  av1_update_sort_order(tx_size, prob, sort_order);
+  av1_update_sort_order(tx_size, tx_type, prob, sort_order);
   for (int i = 0; i < 16; ++i) EXPECT_EQ(ref_sort_order[i], sort_order[i]);
 }
 
 TEST(ScanTest, av1_update_scan_order) {
   TX_SIZE tx_size = TX_4X4;
-  const uint32_t prob[16] = { 4, 5, 7, 4, 5, 6, 8, 2, 3, 3, 2, 2, 2, 2, 2, 2 };
+  const TX_TYPE tx_type = DCT_DCT;
+  const uint32_t prob[16] = { 10, 12, 14, 9, 11, 13, 15, 5,
+                              8,  7,  4,  2, 6,  3,  1,  0 };
   int16_t sort_order[16];
   int16_t scan[16];
   int16_t iscan[16];
   const int16_t ref_iscan[16] = { 0, 1, 2,  6,  3, 4,  5,  10,
                                   7, 8, 11, 13, 9, 12, 14, 15 };
 
-  av1_update_sort_order(tx_size, prob, sort_order);
+  av1_update_sort_order(tx_size, tx_type, prob, sort_order);
   av1_update_scan_order(tx_size, sort_order, scan, iscan);
 
   for (int i = 0; i < 16; ++i) {