mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-09 00:37:32 +09:00
This is the reference implementation for the Alliance for Open Media's av1 video code. The commit used was 4d668d7feb1f8abd809d1bca0418570a7f142a36.
110 lines
3.6 KiB
C
110 lines
3.6 KiB
C
/*
|
|
* 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;
|
|
}
|