Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #ifndef AOM_DSP_PROB_H_ |
| 13 | #define AOM_DSP_PROB_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 15 | #include "./aom_config.h" |
| 16 | #include "./aom_dsp_common.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | |
| 18 | #include "aom_ports/mem.h" |
| 19 | |
| 20 | #ifdef __cplusplus |
| 21 | extern "C" { |
| 22 | #endif |
| 23 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 24 | typedef uint8_t aom_prob; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 25 | |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 26 | // TODO(negge): Rename this aom_prob once we remove vpxbool. |
| 27 | typedef uint16_t aom_cdf_prob; |
| 28 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 29 | #define MAX_PROB 255 |
| 30 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 31 | #define aom_prob_half ((aom_prob)128) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 32 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 33 | typedef int8_t aom_tree_index; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 34 | |
| 35 | #define TREE_SIZE(leaf_count) (2 * (leaf_count)-2) |
| 36 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 37 | #define aom_complement(x) (255 - x) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 38 | |
| 39 | #define MODE_MV_COUNT_SAT 20 |
| 40 | |
| 41 | /* We build coding trees compactly in arrays. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 42 | Each node of the tree is a pair of aom_tree_indices. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 43 | Array index often references a corresponding probability table. |
| 44 | Index <= 0 means done encoding/decoding and value = -Index, |
| 45 | Index > 0 means need another bit, specification at index. |
| 46 | Nonnegative indices are always even; processing begins at node 0. */ |
| 47 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 48 | typedef const aom_tree_index aom_tree[]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 49 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 50 | static INLINE aom_prob clip_prob(int p) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 51 | return (p > 255) ? 255 : (p < 1) ? 1 : p; |
| 52 | } |
| 53 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 54 | static INLINE aom_prob get_prob(int num, int den) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 55 | return (den == 0) ? 128u : clip_prob(((int64_t)num * 256 + (den >> 1)) / den); |
| 56 | } |
| 57 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 58 | static INLINE aom_prob get_binary_prob(int n0, int n1) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 59 | return get_prob(n0, n0 + n1); |
| 60 | } |
| 61 | |
| 62 | /* This function assumes prob1 and prob2 are already within [1,255] range. */ |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 63 | static INLINE aom_prob weighted_prob(int prob1, int prob2, int factor) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 64 | return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8); |
| 65 | } |
| 66 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 67 | static INLINE aom_prob merge_probs(aom_prob pre_prob, const unsigned int ct[2], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 68 | unsigned int count_sat, |
| 69 | unsigned int max_update_factor) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 70 | const aom_prob prob = get_binary_prob(ct[0], ct[1]); |
| 71 | const unsigned int count = AOMMIN(ct[0] + ct[1], count_sat); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 72 | const unsigned int factor = max_update_factor * count / count_sat; |
| 73 | return weighted_prob(pre_prob, prob, factor); |
| 74 | } |
| 75 | |
| 76 | // MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT; |
| 77 | static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = { |
| 78 | 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, |
| 79 | 70, 76, 83, 89, 96, 102, 108, 115, 121, 128 |
| 80 | }; |
| 81 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 82 | static INLINE aom_prob mode_mv_merge_probs(aom_prob pre_prob, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 83 | const unsigned int ct[2]) { |
| 84 | const unsigned int den = ct[0] + ct[1]; |
| 85 | if (den == 0) { |
| 86 | return pre_prob; |
| 87 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 88 | const unsigned int count = AOMMIN(den, MODE_MV_COUNT_SAT); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 89 | const unsigned int factor = count_to_update_factor[count]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 90 | const aom_prob prob = |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 91 | clip_prob(((int64_t)(ct[0]) * 256 + (den >> 1)) / den); |
| 92 | return weighted_prob(pre_prob, prob, factor); |
| 93 | } |
| 94 | } |
| 95 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 96 | void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs, |
| 97 | const unsigned int *counts, aom_prob *probs); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 98 | |
Nathan E. Egge | 43acafd | 2016-03-06 13:41:53 -0500 | [diff] [blame^] | 99 | #if CONFIG_DAALA_EC |
| 100 | int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs, |
| 101 | aom_tree_index root, uint16_t *cdf, aom_tree_index *ind, |
| 102 | int *pth, int *len); |
| 103 | #endif |
| 104 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 105 | DECLARE_ALIGNED(16, extern const uint8_t, aom_norm[256]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 106 | |
| 107 | #ifdef __cplusplus |
| 108 | } // extern "C" |
| 109 | #endif |
| 110 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 111 | #endif // AOM_DSP_PROB_H_ |