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 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 12 | #ifndef AOM_AOM_DSP_PROB_H_ |
| 13 | #define AOM_AOM_DSP_PROB_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
James Zern | 751f26a | 2016-09-28 17:39:05 -0700 | [diff] [blame] | 15 | #include <assert.h> |
Dake He | b79f1b6 | 2017-11-19 12:10:59 -0800 | [diff] [blame] | 16 | #include <stdio.h> |
James Zern | 751f26a | 2016-09-28 17:39:05 -0700 | [diff] [blame] | 17 | |
Tom Finegan | 60e653d | 2018-05-22 11:34:58 -0700 | [diff] [blame] | 18 | #include "config/aom_config.h" |
| 19 | |
Tom Finegan | dd3e2a5 | 2018-05-23 14:33:09 -0700 | [diff] [blame] | 20 | #include "aom_dsp/aom_dsp_common.h" |
| 21 | #include "aom_dsp/entcode.h" |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 22 | #include "aom_ports/bitops.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 23 | #include "aom_ports/mem.h" |
| 24 | |
| 25 | #ifdef __cplusplus |
| 26 | extern "C" { |
| 27 | #endif |
| 28 | |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 29 | typedef uint16_t aom_cdf_prob; |
| 30 | |
Thomas Davies | f3eb840 | 2017-02-20 18:20:20 +0000 | [diff] [blame] | 31 | #define CDF_SIZE(x) ((x) + 1) |
Alex Converse | 2ce4bd4 | 2017-02-01 12:00:31 -0800 | [diff] [blame] | 32 | #define CDF_PROB_BITS 15 |
| 33 | #define CDF_PROB_TOP (1 << CDF_PROB_BITS) |
Thomas Daede | 837262b | 2017-11-06 20:07:01 -0800 | [diff] [blame] | 34 | /*The value stored in an iCDF is CDF_PROB_TOP minus the actual cumulative |
| 35 | probability (an "inverse" CDF). |
| 36 | This function converts from one representation to the other (and is its own |
| 37 | inverse).*/ |
| 38 | #define AOM_ICDF(x) (CDF_PROB_TOP - (x)) |
Alex Converse | 2ce4bd4 | 2017-02-01 12:00:31 -0800 | [diff] [blame] | 39 | |
Thomas Daede | e82e577 | 2017-11-06 17:27:10 -0800 | [diff] [blame] | 40 | #define AOM_CDF2(a0) AOM_ICDF(a0), AOM_ICDF(CDF_PROB_TOP), 0 |
| 41 | #define AOM_CDF3(a0, a1) AOM_ICDF(a0), AOM_ICDF(a1), AOM_ICDF(CDF_PROB_TOP), 0 |
| 42 | #define AOM_CDF4(a0, a1, a2) \ |
| 43 | AOM_ICDF(a0), AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(CDF_PROB_TOP), 0 |
| 44 | #define AOM_CDF5(a0, a1, a2, a3) \ |
| 45 | AOM_ICDF(a0) \ |
| 46 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(CDF_PROB_TOP), 0 |
| 47 | #define AOM_CDF6(a0, a1, a2, a3, a4) \ |
| 48 | AOM_ICDF(a0) \ |
| 49 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), \ |
| 50 | AOM_ICDF(CDF_PROB_TOP), 0 |
| 51 | #define AOM_CDF7(a0, a1, a2, a3, a4, a5) \ |
| 52 | AOM_ICDF(a0) \ |
| 53 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 54 | AOM_ICDF(CDF_PROB_TOP), 0 |
| 55 | #define AOM_CDF8(a0, a1, a2, a3, a4, a5, a6) \ |
| 56 | AOM_ICDF(a0) \ |
| 57 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 58 | AOM_ICDF(a6), AOM_ICDF(CDF_PROB_TOP), 0 |
| 59 | #define AOM_CDF9(a0, a1, a2, a3, a4, a5, a6, a7) \ |
| 60 | AOM_ICDF(a0) \ |
| 61 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 62 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(CDF_PROB_TOP), 0 |
| 63 | #define AOM_CDF10(a0, a1, a2, a3, a4, a5, a6, a7, a8) \ |
| 64 | AOM_ICDF(a0) \ |
| 65 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 66 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(CDF_PROB_TOP), 0 |
| 67 | #define AOM_CDF11(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \ |
| 68 | AOM_ICDF(a0) \ |
| 69 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 70 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), \ |
| 71 | AOM_ICDF(CDF_PROB_TOP), 0 |
| 72 | #define AOM_CDF12(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ |
| 73 | AOM_ICDF(a0) \ |
| 74 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 75 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), AOM_ICDF(a10), \ |
| 76 | AOM_ICDF(CDF_PROB_TOP), 0 |
| 77 | #define AOM_CDF13(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ |
| 78 | AOM_ICDF(a0) \ |
| 79 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 80 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), AOM_ICDF(a10), \ |
| 81 | AOM_ICDF(a11), AOM_ICDF(CDF_PROB_TOP), 0 |
| 82 | #define AOM_CDF14(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) \ |
| 83 | AOM_ICDF(a0) \ |
| 84 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 85 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), AOM_ICDF(a10), \ |
| 86 | AOM_ICDF(a11), AOM_ICDF(a12), AOM_ICDF(CDF_PROB_TOP), 0 |
| 87 | #define AOM_CDF15(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) \ |
| 88 | AOM_ICDF(a0) \ |
| 89 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 90 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), AOM_ICDF(a10), \ |
| 91 | AOM_ICDF(a11), AOM_ICDF(a12), AOM_ICDF(a13), AOM_ICDF(CDF_PROB_TOP), 0 |
| 92 | #define AOM_CDF16(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, \ |
| 93 | a14) \ |
| 94 | AOM_ICDF(a0) \ |
| 95 | , AOM_ICDF(a1), AOM_ICDF(a2), AOM_ICDF(a3), AOM_ICDF(a4), AOM_ICDF(a5), \ |
| 96 | AOM_ICDF(a6), AOM_ICDF(a7), AOM_ICDF(a8), AOM_ICDF(a9), AOM_ICDF(a10), \ |
| 97 | AOM_ICDF(a11), AOM_ICDF(a12), AOM_ICDF(a13), AOM_ICDF(a14), \ |
| 98 | AOM_ICDF(CDF_PROB_TOP), 0 |
| 99 | |
Hui Su | 9fdf2e2 | 2018-01-22 14:48:06 -0800 | [diff] [blame] | 100 | static INLINE uint8_t get_prob(unsigned int num, unsigned int den) { |
James Zern | 751f26a | 2016-09-28 17:39:05 -0700 | [diff] [blame] | 101 | assert(den != 0); |
James Zern | 5631019 | 2016-09-27 19:43:03 -0700 | [diff] [blame] | 102 | { |
James Zern | 5f8361a | 2017-02-24 15:36:52 -0800 | [diff] [blame] | 103 | const int p = (int)(((uint64_t)num * 256 + (den >> 1)) / den); |
James Zern | 5631019 | 2016-09-27 19:43:03 -0700 | [diff] [blame] | 104 | // (p > 255) ? 255 : (p < 1) ? 1 : p; |
| 105 | const int clipped_prob = p | ((255 - p) >> 23) | (p == 0); |
Hui Su | 9fdf2e2 | 2018-01-22 14:48:06 -0800 | [diff] [blame] | 106 | return (uint8_t)clipped_prob; |
James Zern | 5631019 | 2016-09-27 19:43:03 -0700 | [diff] [blame] | 107 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 108 | } |
| 109 | |
Satish Kumar Suman | cf7f263 | 2018-12-19 11:53:38 +0530 | [diff] [blame] | 110 | static INLINE void update_cdf(aom_cdf_prob *cdf, int8_t val, int nsymbs) { |
Dake He | 5641635 | 2017-12-26 15:43:34 -0800 | [diff] [blame] | 111 | assert(nsymbs < 17); |
Kyle Siefring | c724dc6 | 2022-07-28 14:07:20 -0400 | [diff] [blame] | 112 | const int count = cdf[nsymbs]; |
Dake He | b79f1b6 | 2017-11-19 12:10:59 -0800 | [diff] [blame] | 113 | |
Kyle Siefring | c724dc6 | 2022-07-28 14:07:20 -0400 | [diff] [blame] | 114 | // rate is computed in the spec as: |
| 115 | // 3 + ( cdf[N] > 15 ) + ( cdf[N] > 31 ) + Min(FloorLog2(N), 2) |
| 116 | // In this case cdf[N] is |count|. |
| 117 | // Min(FloorLog2(N), 2) is 1 for nsymbs == {2, 3} and 2 for all |
| 118 | // nsymbs > 3. So the equation becomes: |
| 119 | // 4 + (count > 15) + (count > 31) + (nsymbs > 3). |
| 120 | // Note that the largest value for count is 32 (it is not incremented beyond |
| 121 | // 32). So using that information: |
| 122 | // count >> 4 is 0 for count from 0 to 15. |
| 123 | // count >> 4 is 1 for count from 16 to 31. |
| 124 | // count >> 4 is 2 for count == 31. |
| 125 | // Now, the equation becomes: |
| 126 | // 4 + (count >> 4) + (nsymbs > 3). |
| 127 | const int rate = 4 + (count >> 4) + (nsymbs > 3); |
| 128 | |
| 129 | int i = 0; |
| 130 | do { |
| 131 | if (i < val) { |
| 132 | cdf[i] += (CDF_PROB_TOP - cdf[i]) >> rate; |
Dake He | b79f1b6 | 2017-11-19 12:10:59 -0800 | [diff] [blame] | 133 | } else { |
Kyle Siefring | c724dc6 | 2022-07-28 14:07:20 -0400 | [diff] [blame] | 134 | cdf[i] -= cdf[i] >> rate; |
Dake He | b79f1b6 | 2017-11-19 12:10:59 -0800 | [diff] [blame] | 135 | } |
Kyle Siefring | c724dc6 | 2022-07-28 14:07:20 -0400 | [diff] [blame] | 136 | } while (++i < nsymbs - 1); |
| 137 | cdf[nsymbs] += (count < 32); |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 138 | } |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 139 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 140 | #ifdef __cplusplus |
| 141 | } // extern "C" |
| 142 | #endif |
| 143 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 144 | #endif // AOM_AOM_DSP_PROB_H_ |