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;
+ }
+}