Add segment_id binarization mismatch test

BUG=aomedia:1520

Change-Id: I2cce48cacecb2a1df61dcb84add641fa56aedde3
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index b2ccb2e..a460bcb 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -255,7 +255,7 @@
 }
 
 #if CONFIG_SPATIAL_SEGMENTATION
-static int neg_deinterleave(int diff, int ref, int max) {
+int av1_neg_deinterleave(int diff, int ref, int max) {
   if (!ref) return diff;
   if (ref >= (max - 1)) return max - diff - 1;
   if (2 * ref < max) {
@@ -306,7 +306,8 @@
   aom_cdf_prob *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num];
   int coded_id = aom_read_symbol(r, pred_cdf, 8, ACCT_STR);
 
-  int segment_id = neg_deinterleave(coded_id, pred, seg->last_active_segid + 1);
+  int segment_id =
+      av1_neg_deinterleave(coded_id, pred, seg->last_active_segid + 1);
 
   if (segment_id < 0 || segment_id > seg->last_active_segid) {
     aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index d34a9ab..b22396d 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -426,7 +426,7 @@
       segment_ids[mi_offset + y * cm->mi_cols + x] = segment_id;
 }
 
-static int neg_interleave(int x, int ref, int max) {
+int av1_neg_interleave(int x, int ref, int max) {
   const int diff = x - ref;
   if (!ref) return x;
   if (ref >= (max - 1)) return -x + max - 1;
@@ -487,7 +487,7 @@
   }
 
   int coded_id =
-      neg_interleave(mbmi->segment_id, pred, seg->last_active_segid + 1);
+      av1_neg_interleave(mbmi->segment_id, pred, seg->last_active_segid + 1);
 
   aom_cdf_prob *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num];
   aom_write_symbol(w, coded_id, pred_cdf, 8);
diff --git a/test/segment_binarization_sync.cc b/test/segment_binarization_sync.cc
new file mode 100644
index 0000000..bd8cf11
--- /dev/null
+++ b/test/segment_binarization_sync.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
+#include "test/acm_random.h"
+
+using libaom_test::ACMRandom;
+
+extern "C" {
+int av1_neg_interleave(int x, int ref, int max);
+int av1_neg_deinterleave(int diff, int ref, int max);
+}
+
+namespace {
+
+struct Segment {
+  int id;
+  int pred;
+  int last_id;
+};
+
+Segment GenerateSegment(int seed) {
+  static const int MAX_SEGMENTS = 8;
+
+  ACMRandom rnd_(seed);
+
+  Segment segment;
+  const int last_segid = rnd_.PseudoUniform(MAX_SEGMENTS);
+  segment.last_id = last_segid;
+  segment.pred = rnd_.PseudoUniform(MAX_SEGMENTS);
+  segment.id = rnd_.PseudoUniform(last_segid + 1);
+
+  return segment;
+}
+
+// Try to reveal a mismatch between segment binarization and debinarization
+TEST(SegmentBinarizationSync, SearchForBinarizationMismatch) {
+  const int count_tests = 1000;
+  const int seed_init = 4321;
+
+  for (int i = 0; i < count_tests; ++i) {
+    const Segment seg = GenerateSegment(seed_init + i);
+
+    const int max_segid = seg.last_id + 1;
+    const int seg_diff = av1_neg_interleave(seg.id, seg.pred, max_segid);
+    const int decoded_segid =
+        av1_neg_deinterleave(seg_diff, seg.pred, max_segid);
+
+    ASSERT_EQ(decoded_segid, seg.id);
+  }
+}
+
+}  // namespace
diff --git a/test/test.cmake b/test/test.cmake
index 1b64b52..fc89920 100644
--- a/test/test.cmake
+++ b/test/test.cmake
@@ -301,6 +301,12 @@
         "${AOM_ROOT}/test/superframe_test.cc"
         "${AOM_ROOT}/test/tile_independence_test.cc")
 
+  if (CONFIG_SPATIAL_SEGMENTATION)
+    set(AOM_UNIT_TEST_COMMON_SOURCES
+        ${AOM_UNIT_TEST_COMMON_SOURCES}
+        "${AOM_ROOT}/test/segment_binarization_sync.cc")
+  endif ()
+
     set(AOM_UNIT_TEST_COMMON_SOURCES
         ${AOM_UNIT_TEST_COMMON_SOURCES}
         "${AOM_ROOT}/test/binary_codes_test.cc"