/src/avm/av2/common/hr_coding.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2024, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 3-Clause Clear License |
5 | | * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear |
6 | | * License was not distributed with this source code in the LICENSE file, you |
7 | | * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the |
8 | | * Alliance for Open Media Patent License 1.0 was not distributed with this |
9 | | * source code in the PATENTS file, you can obtain it at |
10 | | * aomedia.org/license/patent-license/. |
11 | | */ |
12 | | |
13 | | #include "av2/common/hr_coding.h" |
14 | | #include "avm/internal/avm_codec_internal.h" |
15 | | |
16 | | /* |
17 | | * This is a table hosting the threshold values for deriving the |
18 | | * Rice parameter m based on input context value ctx. For context |
19 | | * value between two adjacent threshold values, the Rice parameter |
20 | | * m corresponds to the table index i, m=i+1, such that: |
21 | | * |
22 | | * adaptive_table[i] <= ctx < adaptive_table[i+1] |
23 | | * |
24 | | * For context values greater than 64, the Rice parameter stays at m=6. |
25 | | * |
26 | | */ |
27 | | static int adaptive_table[] = { 4, 8, 16, 32, 64 }; |
28 | | |
29 | 189k | int get_adaptive_param(int ctx) { |
30 | 189k | const int table_size = sizeof(adaptive_table) / sizeof(int); |
31 | 189k | int m = 0; |
32 | 226k | while (m < table_size && ctx >= adaptive_table[m]) ++m; |
33 | 189k | return m + 1; |
34 | 189k | } |
35 | | |
36 | 0 | int get_truncated_rice_length(int level, int m, int k, int cmax) { |
37 | 0 | int q = level >> m; |
38 | 0 | if (q >= cmax) return cmax + get_exp_golomb_length(level - (cmax << m), k); |
39 | | |
40 | 0 | return q + 1 + m; |
41 | 0 | } |
42 | | |
43 | | int get_truncated_rice_length_diff(int level, int m, int k, int cmax, |
44 | 0 | int *diff) { |
45 | 0 | int q = level >> m; |
46 | |
|
47 | 0 | if (q >= cmax) { |
48 | 0 | int lshifted = level - (cmax << m); |
49 | 0 | if (lshifted == 0) { |
50 | 0 | int golomb_len0 = k + 1; |
51 | | // diff = (cmax + golomb_len0) - (cmax - 1 + 1 + m) |
52 | 0 | *diff = golomb_len0 - m; |
53 | 0 | return cmax + golomb_len0; |
54 | 0 | } |
55 | 0 | return cmax + get_exp_golomb_length_diff(lshifted, k, diff); |
56 | 0 | } |
57 | | |
58 | 0 | if (level == 0) { |
59 | 0 | *diff = m + 1; |
60 | 0 | return m + 1; |
61 | 0 | } |
62 | | |
63 | 0 | *diff = level == (q << m); |
64 | 0 | return q + 1 + m; |
65 | 0 | } |
66 | | |
67 | 0 | int get_adaptive_hr_length(int level, int ctx) { |
68 | 0 | int m = get_adaptive_param(ctx); |
69 | 0 | return get_truncated_rice_length(level, m, m + 1, AVMMIN(m + 4, 6)); |
70 | 0 | } |
71 | | |
72 | 0 | int get_adaptive_hr_length_diff(int level, int ctx, int *diff) { |
73 | 0 | int m = get_adaptive_param(ctx); |
74 | 0 | return get_truncated_rice_length_diff(level, m, m + 1, AVMMIN(m + 4, 6), |
75 | 0 | diff); |
76 | 0 | } |