summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/decoder/generic_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/decoder/generic_decoder.c')
-rw-r--r--third_party/aom/av1/decoder/generic_decoder.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/third_party/aom/av1/decoder/generic_decoder.c b/third_party/aom/av1/decoder/generic_decoder.c
new file mode 100644
index 000000000..0c7d71b9f
--- /dev/null
+++ b/third_party/aom/av1/decoder/generic_decoder.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2001-2016, 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.
+ */
+
+/* clang-format off */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "aom_dsp/bitreader.h"
+#include "av1/common/generic_code.h"
+#include "av1/common/odintrin.h"
+#include "pvq_decoder.h"
+
+/** Decodes a value from 0 to N-1 (with N up to 16) based on a cdf and adapts
+ * the cdf accordingly.
+ *
+ * @param [in,out] r multi-symbol entropy decoder
+ * @param [in,out] cdf CDF of the variable (Q15)
+ * @param [in] n number of values possible
+ * @param [in,out] count number of symbols encoded with that cdf so far
+ * @param [in] rate adaptation rate shift (smaller is faster)
+ * @return decoded variable
+ */
+int aom_decode_cdf_adapt_q15_(aom_reader *r, uint16_t *cdf, int n,
+ int *count, int rate ACCT_STR_PARAM) {
+ int val;
+ int i;
+ if (*count == 0) {
+ int ft;
+ ft = cdf[n - 1];
+ for (i = 0; i < n; i++) {
+ cdf[i] = AOM_ICDF(cdf[i]*32768/ft);
+ }
+ }
+ val = aom_read_cdf(r, cdf, n, ACCT_STR_NAME);
+ aom_cdf_adapt_q15(val, cdf, n, count, rate);
+ return val;
+}
+
+/** Encodes a random variable using a "generic" model, assuming that the
+ * distribution is one-sided (zero and up), has a single mode, and decays
+ * exponentially past the model.
+ *
+ * @param [in,out] r multi-symbol entropy decoder
+ * @param [in,out] model generic probability model
+ * @param [in] x variable being encoded
+ * @param [in,out] ExQ16 expectation of x (adapted)
+ * @param [in] integration integration period of ExQ16 (leaky average over
+ * 1<<integration samples)
+ *
+ * @retval decoded variable x
+ */
+int generic_decode_(aom_reader *r, generic_encoder *model,
+ int *ex_q16, int integration ACCT_STR_PARAM) {
+ int lg_q1;
+ int shift;
+ int id;
+ uint16_t *cdf;
+ int xs;
+ int lsb;
+ int x;
+ lsb = 0;
+ lg_q1 = log_ex(*ex_q16);
+ /* If expectation is too large, shift x to ensure that
+ all we have past xs=15 is the exponentially decaying tail
+ of the distribution. */
+ shift = OD_MAXI(0, (lg_q1 - 5) >> 1);
+ /* Choose the cdf to use: we have two per "octave" of ExQ16. */
+ id = OD_MINI(GENERIC_TABLES - 1, lg_q1);
+ cdf = model->cdf[id];
+ xs = aom_read_symbol_pvq(r, cdf, 16, ACCT_STR_NAME);
+ if (xs == 15) {
+ int e;
+ unsigned decay;
+ /* Estimate decay based on the assumption that the distribution is close
+ to Laplacian for large values. We should probably have an adaptive
+ estimate instead. Note: The 2* is a kludge that's not fully understood
+ yet. */
+ OD_ASSERT(*ex_q16 < INT_MAX >> 1);
+ e = ((2**ex_q16 >> 8) + (1 << shift >> 1)) >> shift;
+ decay = OD_MAXI(2, OD_MINI(254, 256*e/(e + 256)));
+ xs += aom_laplace_decode_special(r, decay, ACCT_STR_NAME);
+ }
+ if (shift != 0) {
+ int special;
+ /* Because of the rounding, there's only half the number of possibilities
+ for xs=0 */
+ special = xs == 0;
+ if (shift - special > 0) {
+ lsb = aom_read_literal(r, shift - special, ACCT_STR_NAME);
+ }
+ lsb -= !special << (shift - 1);
+ }
+ x = (xs << shift) + lsb;
+ generic_model_update(ex_q16, x, integration);
+ OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG,
+ "dec: %d %d %d %d %d %x", *ex_q16, x, shift, id, xs, dec->rng));
+ return x;
+}