blob: 782e4b33fee7bcd7de2b034999c7a17f17d32ccc [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AOM_DSP_PROB_H_
13#define AOM_DSP_PROB_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
16#include "./aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Thomas9ac55082016-09-23 18:04:17 +010018#include "aom_ports/bitops.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_ports/mem.h"
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
Yaowu Xuf883b422016-08-30 14:01:10 -070025typedef uint8_t aom_prob;
Yaowu Xuc27fc142016-08-22 16:08:15 -070026
Alex Conversea1ac9722016-10-12 15:59:58 -070027// TODO(negge): Rename this aom_prob once we remove vpxbool.
28typedef uint16_t aom_cdf_prob;
29
Yaowu Xuc27fc142016-08-22 16:08:15 -070030#define MAX_PROB 255
31
Yaowu Xuf883b422016-08-30 14:01:10 -070032#define aom_prob_half ((aom_prob)128)
Yaowu Xuc27fc142016-08-22 16:08:15 -070033
Yaowu Xuf883b422016-08-30 14:01:10 -070034typedef int8_t aom_tree_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -070035
Yaowu Xu8af861b2016-11-01 12:12:11 -070036#define TREE_SIZE(leaf_count) (-2 + 2 * (leaf_count))
Yaowu Xuc27fc142016-08-22 16:08:15 -070037
Yaowu Xuf883b422016-08-30 14:01:10 -070038#define aom_complement(x) (255 - x)
Yaowu Xuc27fc142016-08-22 16:08:15 -070039
40#define MODE_MV_COUNT_SAT 20
41
42/* We build coding trees compactly in arrays.
Yaowu Xuf883b422016-08-30 14:01:10 -070043 Each node of the tree is a pair of aom_tree_indices.
Yaowu Xuc27fc142016-08-22 16:08:15 -070044 Array index often references a corresponding probability table.
45 Index <= 0 means done encoding/decoding and value = -Index,
46 Index > 0 means need another bit, specification at index.
47 Nonnegative indices are always even; processing begins at node 0. */
48
Yaowu Xuf883b422016-08-30 14:01:10 -070049typedef const aom_tree_index aom_tree[];
Yaowu Xuc27fc142016-08-22 16:08:15 -070050
Yaowu Xuf883b422016-08-30 14:01:10 -070051static INLINE aom_prob clip_prob(int p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070052 return (p > 255) ? 255 : (p < 1) ? 1 : p;
53}
54
Yaowu Xuf883b422016-08-30 14:01:10 -070055static INLINE aom_prob get_prob(int num, int den) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070056 return (den == 0) ? 128u : clip_prob(((int64_t)num * 256 + (den >> 1)) / den);
57}
58
Yaowu Xuf883b422016-08-30 14:01:10 -070059static INLINE aom_prob get_binary_prob(int n0, int n1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070060 return get_prob(n0, n0 + n1);
61}
62
63/* This function assumes prob1 and prob2 are already within [1,255] range. */
Yaowu Xuf883b422016-08-30 14:01:10 -070064static INLINE aom_prob weighted_prob(int prob1, int prob2, int factor) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8);
66}
67
Yaowu Xuf883b422016-08-30 14:01:10 -070068static INLINE aom_prob merge_probs(aom_prob pre_prob, const unsigned int ct[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -070069 unsigned int count_sat,
70 unsigned int max_update_factor) {
Yaowu Xuf883b422016-08-30 14:01:10 -070071 const aom_prob prob = get_binary_prob(ct[0], ct[1]);
72 const unsigned int count = AOMMIN(ct[0] + ct[1], count_sat);
Yaowu Xuc27fc142016-08-22 16:08:15 -070073 const unsigned int factor = max_update_factor * count / count_sat;
74 return weighted_prob(pre_prob, prob, factor);
75}
76
77// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
78static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = {
79 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
80 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
81};
82
Yaowu Xuf883b422016-08-30 14:01:10 -070083static INLINE aom_prob mode_mv_merge_probs(aom_prob pre_prob,
Yaowu Xuc27fc142016-08-22 16:08:15 -070084 const unsigned int ct[2]) {
85 const unsigned int den = ct[0] + ct[1];
86 if (den == 0) {
87 return pre_prob;
88 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -070089 const unsigned int count = AOMMIN(den, MODE_MV_COUNT_SAT);
Yaowu Xuc27fc142016-08-22 16:08:15 -070090 const unsigned int factor = count_to_update_factor[count];
Yaowu Xuf883b422016-08-30 14:01:10 -070091 const aom_prob prob =
Yaowu Xuc27fc142016-08-22 16:08:15 -070092 clip_prob(((int64_t)(ct[0]) * 256 + (den >> 1)) / den);
93 return weighted_prob(pre_prob, prob, factor);
94 }
95}
96
Yaowu Xuf883b422016-08-30 14:01:10 -070097void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
98 const unsigned int *counts, aom_prob *probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -070099
Alex Converseaca9feb2016-10-10 11:08:10 -0700100#if CONFIG_EC_MULTISYMBOL
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500101int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400102 aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *ind,
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500103 int *pth, int *len);
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400104
105static INLINE void av1_tree_to_cdf(const aom_tree_index *tree,
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400106 const aom_prob *probs, aom_cdf_prob *cdf) {
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400107 aom_tree_index index[16];
108 int path[16];
109 int dist[16];
110 tree_to_cdf(tree, probs, 0, cdf, index, path, dist);
111}
112
113#define av1_tree_to_cdf_1D(tree, probs, cdf, u) \
114 do { \
115 int i; \
116 for (i = 0; i < u; i++) { \
117 av1_tree_to_cdf(tree, probs[i], cdf[i]); \
118 } \
119 } while (0)
120
Nathan E. Egge439c5022016-07-17 23:07:27 -0400121#define av1_tree_to_cdf_2D(tree, probs, cdf, v, u) \
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400122 do { \
123 int j; \
124 int i; \
125 for (j = 0; j < v; j++) { \
126 for (i = 0; i < u; i++) { \
127 av1_tree_to_cdf(tree, probs[j][i], cdf[j][i]); \
128 } \
129 } \
130 } while (0)
Nathan E. Egge8abf8672016-07-20 13:12:31 -0400131
132void av1_indices_from_tree(int *ind, int *inv, int len,
133 const aom_tree_index *tree);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500134#endif
135
Yaowu Xuf883b422016-08-30 14:01:10 -0700136DECLARE_ALIGNED(16, extern const uint8_t, aom_norm[256]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137
Thomas9ac55082016-09-23 18:04:17 +0100138#if CONFIG_EC_ADAPT
139static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100140 const int rate = 4 + get_msb(nsymbs);
Thomas Daviesef97ec02016-12-09 14:42:02 +0000141 const int rate2 = 12 - rate;
142 int i, tmp;
143 int diff;
144#if 1
145 const int tmp0 = 1 << rate2;
146 tmp = tmp0;
147 diff = ((32768 - (nsymbs << rate2)) >> rate) << rate;
148 // Single loop (faster)
149 for (i = 0; i < nsymbs - 1; ++i, tmp += tmp0) {
150 tmp += (i == val ? diff : 0);
151 cdf[i] -= ((cdf[i] - tmp) >> rate);
152 }
153#else
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100154 for (i = 0; i < nsymbs; ++i) {
Thomas Daviesef97ec02016-12-09 14:42:02 +0000155 tmp = (i + 1) << rate2;
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100156 cdf[i] -= ((cdf[i] - tmp) >> rate);
Thomas9ac55082016-09-23 18:04:17 +0100157 }
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100158 diff = 32768 - cdf[nsymbs - 1];
Thomas9ac55082016-09-23 18:04:17 +0100159
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100160 for (i = val; i < nsymbs; ++i) {
161 cdf[i] += diff;
162 }
Thomas Daviesef97ec02016-12-09 14:42:02 +0000163#endif
Thomas9ac55082016-09-23 18:04:17 +0100164}
165#endif
166
Yaowu Xuc27fc142016-08-22 16:08:15 -0700167#ifdef __cplusplus
168} // extern "C"
169#endif
170
Yaowu Xuf883b422016-08-30 14:01:10 -0700171#endif // AOM_DSP_PROB_H_