blob: cc39b05b3eb1a4a1451e598373d689ebf501f142 [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
James Zern751f26a2016-09-28 17:39:05 -070015#include <assert.h>
16
Yaowu Xuf883b422016-08-30 14:01:10 -070017#include "./aom_config.h"
18#include "./aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
Thomas9ac55082016-09-23 18:04:17 +010020#include "aom_ports/bitops.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
22
Nathan E. Egge476c63c2017-05-18 18:35:16 -040023#if !CONFIG_ANS
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -070024#include "aom_dsp/entcode.h"
25#endif
26
Yaowu Xuc27fc142016-08-22 16:08:15 -070027#ifdef __cplusplus
28extern "C" {
29#endif
30
Yaowu Xuf883b422016-08-30 14:01:10 -070031typedef uint8_t aom_prob;
Yaowu Xuc27fc142016-08-22 16:08:15 -070032
Alex Conversea1ac9722016-10-12 15:59:58 -070033// TODO(negge): Rename this aom_prob once we remove vpxbool.
34typedef uint16_t aom_cdf_prob;
35
Thomas Daviesf3eb8402017-02-20 18:20:20 +000036#define CDF_SIZE(x) ((x) + 1)
Thomas Daviesf3eb8402017-02-20 18:20:20 +000037
Alex Converse2ce4bd42017-02-01 12:00:31 -080038#define CDF_PROB_BITS 15
39#define CDF_PROB_TOP (1 << CDF_PROB_BITS)
40
Nathan E. Egge476c63c2017-05-18 18:35:16 -040041#if !CONFIG_ANS
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -070042#define AOM_ICDF OD_ICDF
43#else
44#define AOM_ICDF(x) (x)
45#endif
46
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#define MAX_PROB 255
48
Jingning Hanfdaa55e2017-08-18 16:21:36 -070049#define LV_MAP_PROB 1
50
Jingning Han87b01b52017-08-31 12:07:20 -070051#define BR_NODE 1
52
Yaowu Xuf883b422016-08-30 14:01:10 -070053#define aom_prob_half ((aom_prob)128)
Yaowu Xuc27fc142016-08-22 16:08:15 -070054
Yaowu Xuf883b422016-08-30 14:01:10 -070055typedef int8_t aom_tree_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -070056
Yaowu Xu8af861b2016-11-01 12:12:11 -070057#define TREE_SIZE(leaf_count) (-2 + 2 * (leaf_count))
Yaowu Xuc27fc142016-08-22 16:08:15 -070058
Yaowu Xuc27fc142016-08-22 16:08:15 -070059#define MODE_MV_COUNT_SAT 20
60
61/* We build coding trees compactly in arrays.
Yaowu Xuf883b422016-08-30 14:01:10 -070062 Each node of the tree is a pair of aom_tree_indices.
Yaowu Xuc27fc142016-08-22 16:08:15 -070063 Array index often references a corresponding probability table.
64 Index <= 0 means done encoding/decoding and value = -Index,
65 Index > 0 means need another bit, specification at index.
66 Nonnegative indices are always even; processing begins at node 0. */
67
Yaowu Xuf883b422016-08-30 14:01:10 -070068typedef const aom_tree_index aom_tree[];
Yaowu Xuc27fc142016-08-22 16:08:15 -070069
Alex Converse19d78222016-07-28 09:53:23 -070070static INLINE aom_prob get_prob(unsigned int num, unsigned int den) {
James Zern751f26a2016-09-28 17:39:05 -070071 assert(den != 0);
James Zern56310192016-09-27 19:43:03 -070072 {
James Zern5f8361a2017-02-24 15:36:52 -080073 const int p = (int)(((uint64_t)num * 256 + (den >> 1)) / den);
James Zern56310192016-09-27 19:43:03 -070074 // (p > 255) ? 255 : (p < 1) ? 1 : p;
75 const int clipped_prob = p | ((255 - p) >> 23) | (p == 0);
76 return (aom_prob)clipped_prob;
77 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070078}
79
Alex Converse19d78222016-07-28 09:53:23 -070080static INLINE aom_prob get_binary_prob(unsigned int n0, unsigned int n1) {
James Zern751f26a2016-09-28 17:39:05 -070081 const unsigned int den = n0 + n1;
82 if (den == 0) return 128u;
83 return get_prob(n0, den);
Yaowu Xuc27fc142016-08-22 16:08:15 -070084}
85
86/* This function assumes prob1 and prob2 are already within [1,255] range. */
Yaowu Xuf883b422016-08-30 14:01:10 -070087static INLINE aom_prob weighted_prob(int prob1, int prob2, int factor) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8);
89}
90
Yaowu Xuf883b422016-08-30 14:01:10 -070091static INLINE aom_prob merge_probs(aom_prob pre_prob, const unsigned int ct[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -070092 unsigned int count_sat,
93 unsigned int max_update_factor) {
Yaowu Xuf883b422016-08-30 14:01:10 -070094 const aom_prob prob = get_binary_prob(ct[0], ct[1]);
95 const unsigned int count = AOMMIN(ct[0] + ct[1], count_sat);
Yaowu Xuc27fc142016-08-22 16:08:15 -070096 const unsigned int factor = max_update_factor * count / count_sat;
97 return weighted_prob(pre_prob, prob, factor);
98}
99
100// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
101static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = {
102 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
103 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
104};
105
Yaowu Xuf883b422016-08-30 14:01:10 -0700106static INLINE aom_prob mode_mv_merge_probs(aom_prob pre_prob,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107 const unsigned int ct[2]) {
108 const unsigned int den = ct[0] + ct[1];
109 if (den == 0) {
110 return pre_prob;
111 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700112 const unsigned int count = AOMMIN(den, MODE_MV_COUNT_SAT);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113 const unsigned int factor = count_to_update_factor[count];
Alex Converse19d78222016-07-28 09:53:23 -0700114 const aom_prob prob = get_prob(ct[0], den);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115 return weighted_prob(pre_prob, prob, factor);
116 }
117}
118
Yaowu Xuf883b422016-08-30 14:01:10 -0700119void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
120 const unsigned int *counts, aom_prob *probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500122int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400123 aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *ind,
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500124 int *pth, int *len);
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400125
126static INLINE void av1_tree_to_cdf(const aom_tree_index *tree,
Nathan E. Egge9ac1f7d2016-08-19 17:16:31 -0400127 const aom_prob *probs, aom_cdf_prob *cdf) {
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400128 aom_tree_index index[16];
129 int path[16];
130 int dist[16];
131 tree_to_cdf(tree, probs, 0, cdf, index, path, dist);
132}
133
134#define av1_tree_to_cdf_1D(tree, probs, cdf, u) \
135 do { \
136 int i; \
137 for (i = 0; i < u; i++) { \
138 av1_tree_to_cdf(tree, probs[i], cdf[i]); \
139 } \
140 } while (0)
141
Nathan E. Egge439c5022016-07-17 23:07:27 -0400142#define av1_tree_to_cdf_2D(tree, probs, cdf, v, u) \
Nathan E. Eggee2ed4112016-05-19 12:11:56 -0400143 do { \
144 int j; \
145 int i; \
146 for (j = 0; j < v; j++) { \
147 for (i = 0; i < u; i++) { \
148 av1_tree_to_cdf(tree, probs[j][i], cdf[j][i]); \
149 } \
150 } \
151 } while (0)
Nathan E. Egge8abf8672016-07-20 13:12:31 -0400152
Jingning Han8e67c052017-03-23 15:47:33 -0700153void av1_indices_from_tree(int *ind, int *inv, const aom_tree_index *tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154
Thomas9ac55082016-09-23 18:04:17 +0100155static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
Thomas Davies27713d92016-12-14 13:36:59 +0000156 const int rate = 4 + (cdf[nsymbs] > 31) + get_msb(nsymbs);
Thomas Davies5dad9a82017-03-20 09:53:16 +0000157 const int rate2 = 5;
Thomas Daviesef97ec02016-12-09 14:42:02 +0000158 int i, tmp;
159 int diff;
160#if 1
161 const int tmp0 = 1 << rate2;
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -0700162 tmp = AOM_ICDF(tmp0);
Alex Converse2ce4bd42017-02-01 12:00:31 -0800163 diff = ((CDF_PROB_TOP - (nsymbs << rate2)) >> rate) << rate;
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -0700164// Single loop (faster)
Timothy B. Terriberryf9ef4f62017-08-25 11:24:18 -0700165#if !CONFIG_ANS
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -0700166 for (i = 0; i < nsymbs - 1; ++i, tmp -= tmp0) {
167 tmp -= (i == val ? diff : 0);
168 cdf[i] += ((tmp - cdf[i]) >> rate);
169 }
170#else
Thomas Daviesef97ec02016-12-09 14:42:02 +0000171 for (i = 0; i < nsymbs - 1; ++i, tmp += tmp0) {
172 tmp += (i == val ? diff : 0);
173 cdf[i] -= ((cdf[i] - tmp) >> rate);
174 }
Timothy B. Terriberryf6c807c2017-03-25 16:09:29 -0700175#endif
Thomas Daviesef97ec02016-12-09 14:42:02 +0000176#else
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100177 for (i = 0; i < nsymbs; ++i) {
Thomas Daviesef97ec02016-12-09 14:42:02 +0000178 tmp = (i + 1) << rate2;
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100179 cdf[i] -= ((cdf[i] - tmp) >> rate);
Thomas9ac55082016-09-23 18:04:17 +0100180 }
Alex Converse2ce4bd42017-02-01 12:00:31 -0800181 diff = CDF_PROB_TOP - cdf[nsymbs - 1];
Thomas9ac55082016-09-23 18:04:17 +0100182
Thomas Daviesf6c04ac2016-10-12 17:54:29 +0100183 for (i = val; i < nsymbs; ++i) {
184 cdf[i] += diff;
185 }
Thomas Daviesef97ec02016-12-09 14:42:02 +0000186#endif
Thomas Davies028b57f2017-02-22 16:42:11 +0000187 cdf[nsymbs] += (cdf[nsymbs] < 32);
Thomas9ac55082016-09-23 18:04:17 +0100188}
Thomas9ac55082016-09-23 18:04:17 +0100189
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190#ifdef __cplusplus
191} // extern "C"
192#endif
193
Yaowu Xuf883b422016-08-30 14:01:10 -0700194#endif // AOM_DSP_PROB_H_