/* * 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 #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<> 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; }