/* * 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/bitwriter.h" #include "av1/common/generic_code.h" #include "av1/common/odintrin.h" #include "pvq_encoder.h" /** Encodes a value from 0 to N-1 (with N up to 16) based on a cdf and adapts * the cdf accordingly. * * @param [in,out] w multi-symbol entropy encoder * @param [in] val variable being encoded * @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) */ void aom_encode_cdf_adapt_q15(aom_writer *w, int val, uint16_t *cdf, int n, int *count, int rate) { int i; if (*count == 0) { /* On the first call, we normalize the cdf to (32768 - n). This should eventually be moved to the state init, but for now it makes it much easier to experiment and convert symbols to the Q15 adaptation.*/ int ft; ft = cdf[n - 1]; for (i = 0; i < n; i++) { cdf[i] = AOM_ICDF(cdf[i]*32768/ft); } } aom_write_cdf(w, val, cdf, n); aom_cdf_adapt_q15(val, cdf, n, count, rate); } /** 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] w multi-symbol entropy encoder * @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 = (x + (1 << shift >> 1)) >> shift; aom_write_symbol_pvq(w, OD_MINI(15, xs), cdf, 16); 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))); /* Encode the tail of the distribution assuming exponential decay. */ aom_laplace_encode_special(w, xs - 15, decay); } 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) { aom_write_literal(w, x - (xs << shift) + (!special << (shift - 1)), shift - special); } } generic_model_update(ex_q16, x, integration); OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG, "enc: %d %d %d %d %d %x", *ex_q16, x, shift, id, xs, enc->rng)); } /** Estimates the cost of encoding a value with generic_encode(). * * @param [in,out] model generic probability model * @param [in] x variable being encoded * @param [in,out] ExQ16 expectation of x (adapted) * @return number of bits (approximation) */ double generic_encode_cost(generic_encoder *model, int x, int *ex_q16) { int lg_q1; int shift; int id; uint16_t *cdf; int xs; int extra; 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 = (x + (1 << shift >> 1)) >> shift; extra = 0; if (shift) extra = shift - (xs == 0); xs = OD_MINI(15, xs); /* Shortcut: assume it's going to cost 2 bits for the Laplace coder. */ if (xs == 15) extra += 2; return extra - OD_LOG2((double)(cdf[xs] - (xs == 0 ? 0 : cdf[xs - 1]))/cdf[15]); } /*Estimates the cost of encoding a value with a given CDF.*/ double od_encode_cdf_cost(int val, uint16_t *cdf, int n) { int total_prob; int prev_prob; double val_prob; OD_ASSERT(n > 0); total_prob = cdf[n - 1]; if (val == 0) { prev_prob = 0; } else { prev_prob = cdf[val - 1]; } val_prob = (cdf[val] - prev_prob) / (double)total_prob; return -OD_LOG2(val_prob); }