blob: e21e81c5f2001edadae7d14f2e180504a4126503 [file] [log] [blame]
Yushin Cho77bba8d2016-11-04 16:36:56 -07001/*
2 * Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12/* clang-format off */
13
14#ifdef HAVE_CONFIG_H
15# include "config.h"
16#endif
17
18#include "generic_code.h"
19
Nathan E. Egge85001422016-11-14 13:38:06 -050020void aom_cdf_init(uint16_t *cdf, int ncdfs, int nsyms, int val, int first) {
Yushin Cho77bba8d2016-11-04 16:36:56 -070021 int i;
22 int j;
23 for (i = 0; i < ncdfs; i++) {
24 for (j = 0; j < nsyms; j++) {
25 cdf[i*nsyms + j] = val*j + first;
26 }
27 }
28}
29
30/** Adapts a Q15 cdf after encoding/decoding a symbol. */
Nathan E. Egged6c2dc42016-11-15 10:07:58 -050031void aom_cdf_adapt_q15(int val, uint16_t *cdf, int n, int *count, int rate) {
Yushin Cho77bba8d2016-11-04 16:36:56 -070032 int i;
33 *count = OD_MINI(*count + 1, 1 << rate);
34 OD_ASSERT(cdf[n - 1] == 32768);
35 if (*count >= 1 << rate) {
36 /* Steady-state adaptation based on a simple IIR with dyadic rate. */
37 for (i = 0; i < n; i++) {
38 int tmp;
39 /* When (i < val), we want the adjustment ((cdf[i] - tmp) >> rate) to be
40 positive so long as (cdf[i] > i + 1), and 0 when (cdf[i] == i + 1),
41 to ensure we don't drive any probabilities to 0. Replacing cdf[i] with
42 (i + 2) and solving ((i + 2 - tmp) >> rate == 1) for tmp produces
43 tmp == i + 2 - (1 << rate). Using this value of tmp with
44 cdf[i] == i + 1 instead gives an adjustment of 0 as desired.
45
46 When (i >= val), we want ((cdf[i] - tmp) >> rate) to be negative so
47 long as cdf[i] < 32768 - (n - 1 - i), and 0 when
48 cdf[i] == 32768 - (n - 1 - i), again to ensure we don't drive any
49 probabilities to 0. Since right-shifting any negative value is still
50 negative, we can solve (32768 - (n - 1 - i) - tmp == 0) for tmp,
51 producing tmp = 32769 - n + i. Using this value of tmp with smaller
52 values of cdf[i] instead gives negative adjustments, as desired.
53
54 Combining the two cases gives the expression below. These could be
55 stored in a lookup table indexed by n and rate to avoid the
56 arithmetic. */
57 tmp = 2 - (1<<rate) + i + (32767 + (1<<rate) - n)*(i >= val);
58 cdf[i] -= (cdf[i] - tmp) >> rate;
59 }
60 }
61 else {
62 int alpha;
63 /* Initial adaptation for the first symbols. The adaptation rate is
64 computed to be equivalent to what od_{en,de}code_cdf_adapt() does
65 when the initial cdf is set to increment/4. */
66 alpha = 4*32768/(n + 4**count);
67 for (i = 0; i < n; i++) {
68 int tmp;
69 tmp = (32768 - n)*(i >= val) + i + 1;
70 cdf[i] -= ((cdf[i] - tmp)*alpha) >> 15;
71 }
72 }
73 OD_ASSERT(cdf[n - 1] == 32768);
74}
75
76/** Initializes the cdfs and freq counts for a model.
77 *
78 * @param [out] model model being initialized
79 */
80void generic_model_init(generic_encoder *model) {
81 int i;
82 int j;
83 model->increment = 64;
84 for (i = 0; i < GENERIC_TABLES; i++) {
85 for (j = 0; j < 16; j++) {
86 /* Do flat initialization equivalent to a single symbol in each bin. */
87 model->cdf[i][j] = (j + 1) * model->increment;
88 }
89 }
90}
91
92/** Takes the base-2 log of E(x) in Q1.
93 *
94 * @param [in] ExQ16 expectation of x in Q16
95 *
96 * @retval 2*log2(ExQ16/2^16)
97 */
98int log_ex(int ex_q16) {
99 int lg;
100 int lg_q1;
101 int odd;
102 lg = OD_ILOG(ex_q16);
103 if (lg < 15) {
104 odd = ex_q16*ex_q16 > 2 << 2*lg;
105 }
106 else {
107 int tmp;
108 tmp = ex_q16 >> (lg - 8);
109 odd = tmp*tmp > (1 << 15);
110 }
111 lg_q1 = OD_MAXI(0, 2*lg - 33 + odd);
112 return lg_q1;
113}
114
115/** Updates the probability model based on the encoded/decoded value
116 *
117 * @param [in,out] model generic prob model
118 * @param [in,out] ExQ16 expectation of x
119 * @param [in] x variable encoded/decoded (used for ExQ16)
120 * @param [in] xs variable x after shift (used for the model)
121 * @param [in] id id of the icdf to adapt
122 * @param [in] integration integration period of ExQ16 (leaky average over
123 * 1<<integration samples)
124 */
125void generic_model_update(generic_encoder *model, int *ex_q16, int x, int xs,
126 int id, int integration) {
127 int i;
128 int xenc;
129 uint16_t *cdf;
130 cdf = model->cdf[id];
131 /* Renormalize if we cannot add increment */
132 if (cdf[15] + model->increment > 32767) {
133 for (i = 0; i < 16; i++) {
134 /* Second term ensures that the pdf is non-null */
135 cdf[i] = (cdf[i] >> 1) + i + 1;
136 }
137 }
138 /* Update freq count */
139 xenc = OD_MINI(15, xs);
140 /* This can be easily vectorized */
141 for (i = xenc; i < 16; i++) cdf[i] += model->increment;
142 /* We could have saturated ExQ16 directly, but this is safe and simpler */
143 x = OD_MINI(x, 32767);
144 OD_IIR_DIADIC(*ex_q16, x << 16, integration);
145}