1 /* 2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef VPX_DSP_PROB_H_ 12 #define VPX_DSP_PROB_H_ 13 14 #include <assert.h> 15 16 #include "./vpx_config.h" 17 #include "./vpx_dsp_common.h" 18 19 #include "vpx_ports/mem.h" 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 typedef uint8_t vpx_prob; 26 27 #define MAX_PROB 255 28 29 #define vpx_prob_half ((vpx_prob)128) 30 31 typedef int8_t vpx_tree_index; 32 33 #define TREE_SIZE(leaf_count) (2 * (leaf_count)-2) 34 35 #define vpx_complement(x) (255 - x) 36 37 #define MODE_MV_COUNT_SAT 20 38 39 /* We build coding trees compactly in arrays. 40 Each node of the tree is a pair of vpx_tree_indices. 41 Array index often references a corresponding probability table. 42 Index <= 0 means done encoding/decoding and value = -Index, 43 Index > 0 means need another bit, specification at index. 44 Nonnegative indices are always even; processing begins at node 0. */ 45 46 typedef const vpx_tree_index vpx_tree[]; 47 48 static INLINE vpx_prob get_prob(unsigned int num, unsigned int den) { 49 assert(den != 0); 50 { 51 const int p = (int)(((uint64_t)num * 256 + (den >> 1)) / den); 52 // (p > 255) ? 255 : (p < 1) ? 1 : p; 53 const int clipped_prob = p | ((255 - p) >> 23) | (p == 0); 54 return (vpx_prob)clipped_prob; 55 } 56 } 57 58 static INLINE vpx_prob get_binary_prob(unsigned int n0, unsigned int n1) { 59 const unsigned int den = n0 + n1; 60 if (den == 0) return 128u; 61 return get_prob(n0, den); 62 } 63 64 /* This function assumes prob1 and prob2 are already within [1,255] range. */ 65 static INLINE vpx_prob weighted_prob(int prob1, int prob2, int factor) { 66 return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8); 67 } 68 69 static INLINE vpx_prob merge_probs(vpx_prob pre_prob, const unsigned int ct[2], 70 unsigned int count_sat, 71 unsigned int max_update_factor) { 72 const vpx_prob prob = get_binary_prob(ct[0], ct[1]); 73 const unsigned int count = VPXMIN(ct[0] + ct[1], count_sat); 74 const unsigned int factor = max_update_factor * count / count_sat; 75 return weighted_prob(pre_prob, prob, factor); 76 } 77 78 // MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT; 79 static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = { 80 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, 81 70, 76, 83, 89, 96, 102, 108, 115, 121, 128 82 }; 83 84 static INLINE vpx_prob mode_mv_merge_probs(vpx_prob pre_prob, 85 const unsigned int ct[2]) { 86 const unsigned int den = ct[0] + ct[1]; 87 if (den == 0) { 88 return pre_prob; 89 } else { 90 const unsigned int count = VPXMIN(den, MODE_MV_COUNT_SAT); 91 const unsigned int factor = count_to_update_factor[count]; 92 const vpx_prob prob = get_prob(ct[0], den); 93 return weighted_prob(pre_prob, prob, factor); 94 } 95 } 96 97 void vpx_tree_merge_probs(const vpx_tree_index *tree, const vpx_prob *pre_probs, 98 const unsigned int *counts, vpx_prob *probs); 99 100 DECLARE_ALIGNED(16, extern const uint8_t, vpx_norm[256]); 101 102 #ifdef __cplusplus 103 } // extern "C" 104 #endif 105 106 #endif // VPX_DSP_PROB_H_ 107