blob: 75a0d3fbca4605365b03ce0d510a640902dd985b [file] [log] [blame]
Dmitry Kovalevb5c92612013-12-16 12:53:09 -08001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Dmitry Kovalevb5c92612013-12-16 12:53:09 -08003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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.
Dmitry Kovalevb5c92612013-12-16 12:53:09 -080010 */
11
Nathan E. Eggea67c0ff2016-07-15 16:56:03 -040012#include "./aom_config.h"
13
Alex Converseaca9feb2016-10-10 11:08:10 -070014#if CONFIG_EC_MULTISYMBOL
Nathan E. Egge43acafd2016-03-06 13:41:53 -050015#include <string.h>
16#endif
17
Nathan E. Egge0435f0e2016-06-21 13:02:36 -040018#include "aom_dsp/prob.h"
Dmitry Kovalevb5c92612013-12-16 12:53:09 -080019
Nathan E. Egge43acafd2016-03-06 13:41:53 -050020#if CONFIG_DAALA_EC
21#include "aom_dsp/entcode.h"
22#endif
23
Yaowu Xuf883b422016-08-30 14:01:10 -070024const uint8_t aom_norm[256] = {
clang-format1214cee2016-08-08 22:59:08 -070025 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
26 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
27 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
28 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
29 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Dmitry Kovalevb5c92612013-12-16 12:53:09 -080035};
Jim Bankoski69f58b42014-02-10 07:39:12 -080036
Jim Bankoski69f58b42014-02-10 07:39:12 -080037static unsigned int tree_merge_probs_impl(unsigned int i,
Yaowu Xuf883b422016-08-30 14:01:10 -070038 const aom_tree_index *tree,
39 const aom_prob *pre_probs,
Jim Bankoski69f58b42014-02-10 07:39:12 -080040 const unsigned int *counts,
Yaowu Xuf883b422016-08-30 14:01:10 -070041 aom_prob *probs) {
Jim Bankoski69f58b42014-02-10 07:39:12 -080042 const int l = tree[i];
clang-format1214cee2016-08-08 22:59:08 -070043 const unsigned int left_count =
44 (l <= 0) ? counts[-l]
45 : tree_merge_probs_impl(l, tree, pre_probs, counts, probs);
Jim Bankoski69f58b42014-02-10 07:39:12 -080046 const int r = tree[i + 1];
clang-format1214cee2016-08-08 22:59:08 -070047 const unsigned int right_count =
48 (r <= 0) ? counts[-r]
49 : tree_merge_probs_impl(r, tree, pre_probs, counts, probs);
Jim Bankoski69f58b42014-02-10 07:39:12 -080050 const unsigned int ct[2] = { left_count, right_count };
Yaowu Xueda17972015-01-22 15:27:43 -080051 probs[i >> 1] = mode_mv_merge_probs(pre_probs[i >> 1], ct);
Jim Bankoski69f58b42014-02-10 07:39:12 -080052 return left_count + right_count;
53}
54
Yaowu Xuf883b422016-08-30 14:01:10 -070055void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
56 const unsigned int *counts, aom_prob *probs) {
Yaowu Xueda17972015-01-22 15:27:43 -080057 tree_merge_probs_impl(0, tree, pre_probs, counts, probs);
Jim Bankoski69f58b42014-02-10 07:39:12 -080058}
Nathan E. Egge43acafd2016-03-06 13:41:53 -050059
Alex Converseaca9feb2016-10-10 11:08:10 -070060#if CONFIG_EC_MULTISYMBOL
Nathan E. Egge43acafd2016-03-06 13:41:53 -050061typedef struct tree_node tree_node;
62
63struct tree_node {
64 aom_tree_index index;
65 uint8_t probs[16];
66 uint8_t prob;
67 int path;
68 int len;
69 int l;
70 int r;
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -040071 aom_cdf_prob pdf;
Nathan E. Egge43acafd2016-03-06 13:41:53 -050072};
73
74/* Compute the probability of this node in Q23 */
75static uint32_t tree_node_prob(tree_node n, int i) {
76 uint32_t prob;
77 /* 1.0 in Q23 */
78 prob = 16777216;
79 for (; i < n.len; i++) {
80 prob = prob * n.probs[i] >> 8;
81 }
82 return prob;
83}
84
85static int tree_node_cmp(tree_node a, tree_node b) {
86 int i;
87 uint32_t pa;
88 uint32_t pb;
Alex Converse3fc98e82016-10-05 11:32:05 -070089 for (i = 0; i < AOMMIN(a.len, b.len) && a.probs[i] == b.probs[i]; i++) {
Nathan E. Egge43acafd2016-03-06 13:41:53 -050090 }
91 pa = tree_node_prob(a, i);
92 pb = tree_node_prob(b, i);
93 return pa > pb ? 1 : pa < pb ? -1 : 0;
94}
95
96/* Given a Q15 probability for symbol subtree rooted at tree[n], this function
97 computes the probability of each symbol (defined as a node that has no
98 children). */
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -040099static aom_cdf_prob tree_node_compute_probs(tree_node *tree, int n,
100 aom_cdf_prob pdf) {
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500101 if (tree[n].l == 0) {
102 /* This prevents probability computations in Q15 that underflow from
103 producing a symbol that has zero probability. */
104 if (pdf == 0) pdf = 1;
105 tree[n].pdf = pdf;
106 return pdf;
107 } else {
108 /* We process the smaller probability first, */
109 if (tree[n].prob < 128) {
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400110 aom_cdf_prob lp;
111 aom_cdf_prob rp;
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500112 lp = (((uint32_t)pdf) * tree[n].prob + 128) >> 8;
113 lp = tree_node_compute_probs(tree, tree[n].l, lp);
114 rp = tree_node_compute_probs(tree, tree[n].r, lp > pdf ? 0 : pdf - lp);
115 return lp + rp;
116 } else {
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400117 aom_cdf_prob rp;
118 aom_cdf_prob lp;
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500119 rp = (((uint32_t)pdf) * (256 - tree[n].prob) + 128) >> 8;
120 rp = tree_node_compute_probs(tree, tree[n].r, rp);
121 lp = tree_node_compute_probs(tree, tree[n].l, rp > pdf ? 0 : pdf - rp);
122 return lp + rp;
123 }
124 }
125}
126
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400127static int tree_node_extract(tree_node *tree, int n, int symb,
128 aom_cdf_prob *pdf, aom_tree_index *index,
129 int *path, int *len) {
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500130 if (tree[n].l == 0) {
131 pdf[symb] = tree[n].pdf;
132 if (index != NULL) index[symb] = tree[n].index;
133 if (path != NULL) path[symb] = tree[n].path;
134 if (len != NULL) len[symb] = tree[n].len;
135 return symb + 1;
136 } else {
137 symb = tree_node_extract(tree, tree[n].l, symb, pdf, index, path, len);
138 return tree_node_extract(tree, tree[n].r, symb, pdf, index, path, len);
139 }
140}
141
142int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400143 aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *index,
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500144 int *path, int *len) {
145 tree_node symb[2 * 16 - 1];
146 int nodes;
147 int next[16];
148 int size;
149 int nsymbs;
150 int i;
151 /* Create the root node with probability 1 in Q15. */
152 symb[0].index = root;
153 symb[0].path = 0;
154 symb[0].len = 0;
155 symb[0].l = symb[0].r = 0;
156 nodes = 1;
157 next[0] = 0;
158 size = 1;
159 nsymbs = 1;
160 while (size > 0 && nsymbs < 16) {
161 int m;
162 tree_node n;
163 aom_tree_index j;
164 uint8_t prob;
165 m = 0;
166 /* Find the internal node with the largest probability. */
167 for (i = 1; i < size; i++) {
168 if (tree_node_cmp(symb[next[i]], symb[next[m]]) > 0) m = i;
169 }
170 i = next[m];
171 memmove(&next[m], &next[m + 1], sizeof(*next) * (size - (m + 1)));
172 size--;
173 /* Split this symbol into two symbols */
174 n = symb[i];
175 j = n.index;
176 prob = probs[j >> 1];
177 /* Left */
178 n.index = tree[j];
179 n.path <<= 1;
180 n.len++;
181 n.probs[n.len - 1] = prob;
182 symb[nodes] = n;
183 if (n.index > 0) {
184 next[size++] = nodes;
185 }
186 /* Right */
187 n.index = tree[j + 1];
188 n.path += 1;
189 n.probs[n.len - 1] = 256 - prob;
190 symb[nodes + 1] = n;
191 if (n.index > 0) {
192 next[size++] = nodes + 1;
193 }
194 symb[i].prob = prob;
195 symb[i].l = nodes;
196 symb[i].r = nodes + 1;
197 nodes += 2;
198 nsymbs++;
199 }
200 /* Compute the probabilities of each symbol in Q15 */
Alex Converse2ce4bd42017-02-01 12:00:31 -0800201 tree_node_compute_probs(symb, 0, CDF_PROB_TOP);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500202 /* Extract the cdf, index, path and length */
203 tree_node_extract(symb, 0, 0, cdf, index, path, len);
204 /* Convert to CDF */
205 for (i = 1; i < nsymbs; i++) {
206 cdf[i] = cdf[i - 1] + cdf[i];
207 }
Thomas Davies27713d92016-12-14 13:36:59 +0000208// Store symbol count at the end of the CDF
209#if CONFIG_EC_ADAPT
210 cdf[nsymbs] = 0;
211#endif
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500212 return nsymbs;
213}
Nathan E. Egge8abf8672016-07-20 13:12:31 -0400214
215/* This code assumes that tree contains as unique leaf nodes the integer values
216 0 to len - 1 and produces the forward and inverse mapping tables in ind[]
217 and inv[] respectively. */
218void av1_indices_from_tree(int *ind, int *inv, int len,
219 const aom_tree_index *tree) {
220 int i;
221 int index;
222 for (i = index = 0; i < TREE_SIZE(len); i++) {
223 const aom_tree_index j = tree[i];
224 if (j <= 0) {
225 inv[index] = -j;
226 ind[-j] = index++;
227 }
228 }
229}
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500230#endif