Merge "Fix ransac random generator seeding" into nextgenv2
diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h
index d2fd5f2..ee34275 100644
--- a/aom_dsp/bitreader.h
+++ b/aom_dsp/bitreader.h
@@ -79,6 +79,7 @@
 #endif
 }
 
+// Returns the position in the bit reader in bits.
 static INLINE ptrdiff_t aom_reader_tell(const aom_reader *r) {
 #if CONFIG_ANS
   (void)r;
@@ -91,6 +92,19 @@
 #endif
 }
 
+// Returns the position in the bit reader in 1/8th bits.
+static INLINE ptrdiff_t aom_reader_tell_frac(const aom_reader *r) {
+#if CONFIG_ANS
+  (void)r;
+  assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
+  return 0;
+#elif CONFIG_DAALA_EC
+  return aom_daala_reader_tell_frac(r);
+#else
+  return aom_dk_reader_tell_frac(r);
+#endif
+}
+
 static INLINE int aom_read(aom_reader *r, int prob) {
 #if CONFIG_ANS
   return uabs_read(r, prob);
diff --git a/aom_dsp/daalaboolreader.c b/aom_dsp/daalaboolreader.c
index 8e1c782..65f9d50 100644
--- a/aom_dsp/daalaboolreader.c
+++ b/aom_dsp/daalaboolreader.c
@@ -28,3 +28,7 @@
 ptrdiff_t aom_daala_reader_tell(const daala_reader *r) {
   return od_ec_dec_tell(&r->ec);
 }
+
+ptrdiff_t aom_daala_reader_tell_frac(const daala_reader *r) {
+  return od_ec_dec_tell_frac(&r->ec);
+}
diff --git a/aom_dsp/daalaboolreader.h b/aom_dsp/daalaboolreader.h
index 4fc7ff4..896ec8b 100644
--- a/aom_dsp/daalaboolreader.h
+++ b/aom_dsp/daalaboolreader.h
@@ -30,6 +30,7 @@
 int aom_daala_reader_init(daala_reader *r, const uint8_t *buffer, int size);
 const uint8_t *aom_daala_reader_find_end(daala_reader *r);
 ptrdiff_t aom_daala_reader_tell(const daala_reader *r);
+ptrdiff_t aom_daala_reader_tell_frac(const daala_reader *r);
 
 static INLINE int aom_daala_read(daala_reader *r, int prob) {
   if (prob == 128) {
diff --git a/aom_dsp/dkboolreader.h b/aom_dsp/dkboolreader.h
index 2fd2b37..4d70c53 100644
--- a/aom_dsp/dkboolreader.h
+++ b/aom_dsp/dkboolreader.h
@@ -65,7 +65,29 @@
   const size_t bits_read = (r->buffer - r->buffer_start) * CHAR_BIT;
   const int count =
       (r->count < LOTS_OF_BITS) ? r->count : r->count - LOTS_OF_BITS;
-  return bits_read + BD_VALUE_SIZE - (count + CHAR_BIT);
+  return bits_read - (count + CHAR_BIT);
+}
+
+/*The resolution of fractional-precision bit usage measurements, i.e.,
+   3 => 1/8th bits.*/
+#define DK_BITRES (3)
+
+static INLINE ptrdiff_t aom_dk_reader_tell_frac(const struct aom_dk_reader *r) {
+  uint32_t num_bits;
+  uint32_t range;
+  int l;
+  int i;
+  num_bits = aom_dk_reader_tell(r) << DK_BITRES;
+  range = r->range;
+  l = 0;
+  for (i = DK_BITRES; i-- > 0;) {
+    int b;
+    range = range * range >> 7;
+    b = (int)(range >> 8);
+    l = l << 1 | b;
+    range >>= b;
+  }
+  return num_bits - l;
 }
 
 static INLINE int aom_dk_reader_has_error(struct aom_dk_reader *r) {
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 157f00f..3368ea2 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1325,9 +1325,14 @@
 #endif  // CONFIG_SUPERTX
 
 // FIXME(someone) need real defaults here
-static const struct segmentation_probs default_seg_probs = {
-  { 128, 128, 128, 128, 128, 128, 128 }, { 128, 128, 128 },
+static const aom_prob default_segment_tree_probs[SEG_TREE_PROBS] = {
+  128, 128, 128, 128, 128, 128, 128
 };
+// clang-format off
+static const aom_prob default_segment_pred_probs[PREDICTION_PROBS] = {
+  128, 128, 128
+};
+// clang-format on
 
 static void init_mode_probs(FRAME_CONTEXT *fc) {
   av1_copy(fc->uv_mode_prob, default_uv_probs);
@@ -1372,8 +1377,8 @@
 #if CONFIG_SUPERTX
   av1_copy(fc->supertx_prob, default_supertx_prob);
 #endif  // CONFIG_SUPERTX
-  av1_copy(fc->seg.tree_probs, default_seg_probs.tree_probs);
-  av1_copy(fc->seg.pred_probs, default_seg_probs.pred_probs);
+  av1_copy(fc->seg.tree_probs, default_segment_tree_probs);
+  av1_copy(fc->seg.pred_probs, default_segment_pred_probs);
 #if CONFIG_EXT_INTRA
   av1_copy(fc->ext_intra_probs, default_ext_intra_probs);
   av1_copy(fc->intra_filter_probs, default_intra_filter_probs);
@@ -1392,6 +1397,7 @@
                      fc->inter_ext_tx_cdf, EXT_TX_SIZES);
   av1_tree_to_cdf_1D(av1_partition_tree, fc->partition_prob, fc->partition_cdf,
                      PARTITION_CONTEXTS);
+  av1_tree_to_cdf(av1_segment_tree, fc->seg.tree_probs, fc->seg.tree_cdf);
 #endif
 }
 
diff --git a/av1/common/seg_common.h b/av1/common/seg_common.h
index 8c85d9a..d833a86 100644
--- a/av1/common/seg_common.h
+++ b/av1/common/seg_common.h
@@ -48,6 +48,9 @@
 
 struct segmentation_probs {
   aom_prob tree_probs[SEG_TREE_PROBS];
+#if CONFIG_DAALA_EC
+  aom_cdf_prob tree_cdf[MAX_SEGMENTS];
+#endif
   aom_prob pred_probs[PREDICTION_PROBS];
 };
 
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index bf91a17..ab61cfa 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3672,6 +3672,10 @@
     }
     for (k = 0; k < MAX_SEGMENTS - 1; k++)
       av1_diff_update_prob(&r, &cm->fc->seg.tree_probs[k]);
+#if CONFIG_DAALA_EC
+    av1_tree_to_cdf(av1_segment_tree, cm->fc->seg.tree_probs,
+                    cm->fc->seg.tree_cdf);
+#endif
   }
 
   for (j = 0; j < INTRA_MODES; j++)
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 87ff351..a358f8d 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -207,7 +207,11 @@
 
 static int read_segment_id(aom_reader *r,
                            const struct segmentation_probs *segp) {
+#if CONFIG_DAALA_EC
+  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS);
+#else
   return aom_read_tree(r, av1_segment_tree, segp->tree_probs);
+#endif
 }
 
 #if CONFIG_VAR_TX
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index cca104b..f1e8828 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -807,8 +807,13 @@
 static void write_segment_id(aom_writer *w, const struct segmentation *seg,
                              const struct segmentation_probs *segp,
                              int segment_id) {
-  if (seg->enabled && seg->update_map)
+  if (seg->enabled && seg->update_map) {
+#if CONFIG_DAALA_EC
+    aom_write_symbol(w, segment_id, segp->tree_cdf, MAX_SEGMENTS);
+#else
     aom_write_tree(w, av1_segment_tree, segp->tree_probs, segment_id, 3, 0);
+#endif
+  }
 }
 
 // This function encodes the reference frame
@@ -2739,6 +2744,10 @@
     prob_diff_update(av1_segment_tree, cm->fc->seg.tree_probs,
                      cm->counts.seg.tree_total, MAX_SEGMENTS, w);
   }
+#if CONFIG_DAALA_EC
+  av1_tree_to_cdf(av1_segment_tree, cm->fc->seg.tree_probs,
+                  cm->fc->seg.tree_cdf);
+#endif
 }
 
 static void write_txfm_mode(TX_MODE mode, struct aom_write_bit_buffer *wb) {
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 773e368..3f93d53 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4447,7 +4447,9 @@
     best_param = curr_param;
     for (i = 0; i < n_refinements; i++) {
       // look to the left
-      *param = curr_param - step;
+      *param =
+          (int16_t)clamp(curr_param - step, p < 2 ? GM_TRANS_MIN : GM_ALPHA_MIN,
+                         p < 2 ? GM_TRANS_MAX : GM_ALPHA_MAX);
       step_error =
           av1_warp_erroradv(wm,
 #if CONFIG_AOM_HIGHBITDEPTH
@@ -4464,7 +4466,9 @@
       }
 
       // look to the right
-      *param = curr_param + step;
+      *param =
+          (int16_t)clamp(curr_param + step, p < 2 ? GM_TRANS_MIN : GM_ALPHA_MIN,
+                         p < 2 ? GM_TRANS_MAX : GM_ALPHA_MAX);
       step_error =
           av1_warp_erroradv(wm,
 #if CONFIG_AOM_HIGHBITDEPTH
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 82b75dc..ad33134 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
  *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
+ * 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 <limits.h>
@@ -416,8 +417,6 @@
   // Delete sementation map
   aom_free(cpi->segmentation_map);
   cpi->segmentation_map = NULL;
-  aom_free(cpi->coding_context.last_frame_seg_map_copy);
-  cpi->coding_context.last_frame_seg_map_copy = NULL;
 
 #if CONFIG_REF_MV
   for (i = 0; i < NMV_CONTEXTS; ++i) {
@@ -531,9 +530,6 @@
   memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
          MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));
 
-  memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map,
-         (cm->mi_rows * cm->mi_cols));
-
   av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
   av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
 
@@ -572,9 +568,6 @@
   memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
          MV_VALS * sizeof(*cc->nmvcosts_hp[1]));
 
-  memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy,
-         (cm->mi_rows * cm->mi_cols));
-
   av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
   av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
 
@@ -1895,12 +1888,6 @@
   aom_free(cpi->active_map.map);
   CHECK_MEM_ERROR(cm, cpi->active_map.map,
                   aom_calloc(cm->mi_rows * cm->mi_cols, 1));
-
-  // And a place holder structure is the coding context
-  // for use if we want to save and restore it
-  aom_free(cpi->coding_context.last_frame_seg_map_copy);
-  CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy,
-                  aom_calloc(cm->mi_rows * cm->mi_cols, 1));
 }
 
 void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index a99a5cb..8819655 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1,11 +1,12 @@
 /*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
  *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
+ * 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.
  */
 
 #ifndef AV1_ENCODER_ENCODER_H_
@@ -59,8 +60,6 @@
   int nmv_costs_hp[NMV_CONTEXTS][2][MV_VALS];
 #endif
 
-  unsigned char *last_frame_seg_map_copy;
-
   // 0 = Intra, Last, GF, ARF
   signed char last_ref_lf_deltas[TOTAL_REFS_PER_FRAME];
   // 0 = ZERO_MV, MV
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index bd5ae7e..fef5901 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4137,7 +4137,7 @@
     bits =
         (gm->motion_params.wmmat[0].as_int ? ((GM_ABS_TRANS_BITS + 1) * 2) : 0);
   }
-  return (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype];
+  return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype] : 0;
 }
 
 #define GLOBAL_MOTION_RATE(ref)                            \
@@ -7799,47 +7799,6 @@
   rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
 }
 
-// This function is designed to apply a bias or adjustment to an rd value based
-// on the relative variance of the source and reconstruction.
-#define LOW_VAR_THRESH 16
-#define VLOW_ADJ_MAX 25
-#define VHIGH_ADJ_MAX 8
-static void rd_variance_adjustment(MACROBLOCK *x, int64_t *this_rd,
-                                   MV_REFERENCE_FRAME ref_frame,
-                                   unsigned int source_variance) {
-  unsigned int recon_variance = x->recon_variance;
-  unsigned int absvar_diff = 0;
-  int64_t var_error = 0;
-  int64_t var_factor = 0;
-
-  if (*this_rd == INT64_MAX) return;
-
-  if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
-    absvar_diff = (source_variance > recon_variance)
-                      ? (source_variance - recon_variance)
-                      : (recon_variance - source_variance);
-
-    var_error = ((int64_t)200 * source_variance * recon_variance) /
-                (((int64_t)source_variance * source_variance) +
-                 ((int64_t)recon_variance * recon_variance));
-    var_error = 100 - var_error;
-  }
-
-  // Source variance above a threshold and ref frame is intra.
-  // This case is targeted mainly at discouraging intra modes that give rise
-  // to a predictor with a low spatial complexity compared to the source.
-  if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
-      (source_variance > recon_variance)) {
-    var_factor = AOMMIN(absvar_diff, AOMMIN(VLOW_ADJ_MAX, var_error));
-    // A second possible case of interest is where the source variance
-    // is very low and we wish to discourage false texture or motion trails.
-  } else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
-             (recon_variance > source_variance)) {
-    var_factor = AOMMIN(absvar_diff, AOMMIN(VHIGH_ADJ_MAX, var_error));
-  }
-  *this_rd += (*this_rd * var_factor) / 100;
-}
-
 // Do we have an internal image edge (e.g. formatting bars).
 int av1_internal_image_edge(AV1_COMP *cpi) {
   return (cpi->oxcf.pass == 2) &&
@@ -8098,7 +8057,6 @@
     rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
   }
   this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
-  rd_variance_adjustment(x, &this_rd, INTRA_FRAME, x->source_variance);
 
   if (this_rd < *best_intra_rd) {
     *best_intra_rd = this_rd;
@@ -9165,10 +9123,6 @@
 #endif  // CONFIG_MOTION_VAR
     }
 
-    // Apply an adjustment to the rd value based on the similarity of the
-    // source variance and reconstructed variance.
-    rd_variance_adjustment(x, &this_rd, ref_frame, x->source_variance);
-
     if (ref_frame == INTRA_FRAME) {
       // Keep record of best intra rd
       if (this_rd < best_intra_rd) {
diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c
index dfcb404..3292da4 100644
--- a/av1/encoder/segmentation.c
+++ b/av1/encoder/segmentation.c
@@ -366,6 +366,9 @@
   } else {
     seg->temporal_update = 0;
   }
+#if CONFIG_DAALA_EC
+  av1_tree_to_cdf(av1_segment_tree, segp->tree_probs, segp->tree_cdf);
+#endif
 }
 
 void av1_reset_segment_features(AV1_COMMON *cm) {
diff --git a/configure b/configure
index 3c59c6e..df8364a 100755
--- a/configure
+++ b/configure
@@ -283,6 +283,7 @@
     alt_intra
     palette
     daala_ec
+    cb4x4
 "
 CONFIG_LIST="
     dependency_tracking
diff --git a/test/boolcoder_test.cc b/test/boolcoder_test.cc
index de9b6e4..f1bad33 100644
--- a/test/boolcoder_test.cc
+++ b/test/boolcoder_test.cc
@@ -88,3 +88,54 @@
     }
   }
 }
+
+#if CONFIG_DAALA_EC
+#define FRAC_DIFF_TOTAL_ERROR 0.07
+#else
+#define FRAC_DIFF_TOTAL_ERROR 0.2
+#endif
+
+TEST(AV1, TestTell) {
+  const int kBufferSize = 10000;
+  aom_writer bw;
+  uint8_t bw_buffer[kBufferSize];
+  const int kSymbols = 1024;
+  // Coders are noisier at low probabilities, so we start at p = 4.
+  for (int p = 4; p <= 256; p++) {
+    double probability = p / 256.;
+    aom_start_encode(&bw, bw_buffer);
+    for (int i = 0; i < kSymbols; i++) {
+      aom_write(&bw, 0, p);
+    }
+    aom_stop_encode(&bw);
+    aom_reader br;
+    aom_reader_init(&br, bw_buffer, kBufferSize, NULL, NULL);
+    ptrdiff_t last_tell = aom_reader_tell(&br);
+    ptrdiff_t last_tell_frac = aom_reader_tell_frac(&br);
+    double frac_diff_total = 0;
+    GTEST_ASSERT_GE(aom_reader_tell(&br), 0);
+    GTEST_ASSERT_LE(aom_reader_tell(&br), 1);
+    for (int i = 0; i < kSymbols; i++) {
+      aom_read(&br, p);
+      ptrdiff_t tell = aom_reader_tell(&br);
+      ptrdiff_t tell_frac = aom_reader_tell_frac(&br);
+      GTEST_ASSERT_GE(tell, last_tell) << "tell: " << tell
+                                       << ", last_tell: " << last_tell;
+      GTEST_ASSERT_GE(tell_frac, last_tell_frac)
+          << "tell_frac: " << tell_frac
+          << ", last_tell_frac: " << last_tell_frac;
+      // Frac tell should round up to tell.
+      GTEST_ASSERT_EQ(tell, (tell_frac + 7) >> 3);
+      last_tell = tell;
+      frac_diff_total +=
+          fabs(((tell_frac - last_tell_frac) / 8.0) + log2(probability));
+      last_tell_frac = tell_frac;
+    }
+    const int expected = (int)(-kSymbols * log2(probability));
+    // Last tell should be close to the expected value.
+    GTEST_ASSERT_LE(last_tell - expected, 20) << " last_tell: " << last_tell;
+    // The average frac_diff error should be pretty small.
+    GTEST_ASSERT_LE(frac_diff_total / kSymbols, FRAC_DIFF_TOTAL_ERROR)
+        << " frac_diff_total: " << frac_diff_total;
+  }
+}