Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvpx/vp9/encoder/vp9_subexp.c
Line
Count
Source
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
#include "vpx_dsp/bitwriter.h"
11
12
#include "vp9/common/vp9_common.h"
13
#include "vp9/common/vp9_entropy.h"
14
#include "vp9/encoder/vp9_cost.h"
15
#include "vp9/encoder/vp9_subexp.h"
16
17
static const uint8_t update_bits[255] = {
18
  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,
19
  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  8,  8,  8,  8,  8,  8,
20
  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
21
  8,  8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
22
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
23
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
24
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11,
25
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
26
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
27
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
28
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
29
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
30
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
31
  11, 11, 11, 11, 11, 11, 11, 0,
32
};
33
33.4M
#define MIN_DELP_BITS 5
34
35
221M
static int recenter_nonneg(int v, int m) {
36
221M
  if (v > (m << 1))
37
60.1M
    return v;
38
161M
  else if (v >= m)
39
76.1M
    return ((v - m) << 1);
40
84.9M
  else
41
84.9M
    return ((m - v) << 1) - 1;
42
221M
}
43
44
221M
static int remap_prob(int v, int m) {
45
221M
  int i;
46
221M
  static const uint8_t map_table[MAX_PROB - 1] = {
47
    // generated by:
48
    //   map_table[j] = split_index(j, MAX_PROB - 1, MODULUS_PARAM);
49
221M
    20,  21,  22,  23,  24,  25,  0,   26,  27,  28,  29,  30,  31,  32,  33,
50
221M
    34,  35,  36,  37,  1,   38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
51
221M
    48,  49,  2,   50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
52
221M
    3,   62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  4,   74,
53
221M
    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  5,   86,  87,  88,
54
221M
    89,  90,  91,  92,  93,  94,  95,  96,  97,  6,   98,  99,  100, 101, 102,
55
221M
    103, 104, 105, 106, 107, 108, 109, 7,   110, 111, 112, 113, 114, 115, 116,
56
221M
    117, 118, 119, 120, 121, 8,   122, 123, 124, 125, 126, 127, 128, 129, 130,
57
221M
    131, 132, 133, 9,   134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
58
221M
    145, 10,  146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11,
59
221M
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12,  170, 171,
60
221M
    172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13,  182, 183, 184, 185,
61
221M
    186, 187, 188, 189, 190, 191, 192, 193, 14,  194, 195, 196, 197, 198, 199,
62
221M
    200, 201, 202, 203, 204, 205, 15,  206, 207, 208, 209, 210, 211, 212, 213,
63
221M
    214, 215, 216, 217, 16,  218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
64
221M
    228, 229, 17,  230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
65
221M
    18,  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19,
66
221M
  };
67
221M
  v--;
68
221M
  m--;
69
221M
  assert(m >= 0);
70
221M
  if ((m << 1) <= MAX_PROB)
71
124M
    i = recenter_nonneg(v, m) - 1;
72
96.8M
  else
73
96.8M
    i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1;
74
75
221M
  assert(i >= 0 && (size_t)i < sizeof(map_table));
76
221M
  i = map_table[i];
77
221M
  return i;
78
221M
}
79
80
220M
static int prob_diff_update_cost(vpx_prob newp, vpx_prob oldp) {
81
220M
  int delp = remap_prob(newp, oldp);
82
220M
  return update_bits[delp] << VP9_PROB_COST_SHIFT;
83
220M
}
84
85
54.0k
static void encode_uniform(vpx_writer *w, int v) {
86
54.0k
  const int l = 8;
87
54.0k
  const int m = (1 << l) - 191;
88
54.0k
  if (v < m) {
89
23.5k
    vpx_write_literal(w, v, l - 1);
90
30.4k
  } else {
91
30.4k
    vpx_write_literal(w, m + ((v - m) >> 1), l - 1);
92
30.4k
    vpx_write_literal(w, (v - m) & 1, 1);
93
30.4k
  }
94
54.0k
}
95
96
925k
static INLINE int write_bit_gte(vpx_writer *w, int word, int test) {
97
925k
  vpx_write_literal(w, word >= test, 1);
98
925k
  return word >= test;
99
925k
}
100
101
622k
static void encode_term_subexp(vpx_writer *w, int word) {
102
622k
  if (!write_bit_gte(w, word, 16)) {
103
414k
    vpx_write_literal(w, word, 4);
104
414k
  } else if (!write_bit_gte(w, word, 32)) {
105
114k
    vpx_write_literal(w, word - 16, 4);
106
114k
  } else if (!write_bit_gte(w, word, 64)) {
107
39.7k
    vpx_write_literal(w, word - 32, 5);
108
54.0k
  } else {
109
54.0k
    encode_uniform(w, word - 64);
110
54.0k
  }
111
622k
}
112
113
622k
void vp9_write_prob_diff_update(vpx_writer *w, vpx_prob newp, vpx_prob oldp) {
114
622k
  const int delp = remap_prob(newp, oldp);
115
622k
  encode_term_subexp(w, delp);
116
622k
}
117
118
int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct,
119
                                            vpx_prob oldp, vpx_prob *bestp,
120
24.7M
                                            vpx_prob upd) {
121
24.7M
  const int64_t old_b = cost_branch256(ct, oldp);
122
24.7M
  int64_t bestsavings = 0;
123
24.7M
  vpx_prob newp, bestnewp = oldp;
124
24.7M
  const int step = *bestp > oldp ? -1 : 1;
125
24.7M
  const int upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
126
127
24.7M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
128
98.1M
    for (newp = *bestp; newp != oldp; newp += step) {
129
95.7M
      const int64_t new_b = cost_branch256(ct, newp);
130
95.7M
      const int64_t update_b = prob_diff_update_cost(newp, oldp) + upd_cost;
131
95.7M
      const int64_t savings = old_b - new_b - update_b;
132
95.7M
      if (savings > bestsavings) {
133
819k
        bestsavings = savings;
134
819k
        bestnewp = newp;
135
819k
      }
136
95.7M
    }
137
2.42M
  }
138
24.7M
  *bestp = bestnewp;
139
24.7M
  return bestsavings;
140
24.7M
}
141
142
int64_t vp9_prob_diff_update_savings_search_model(const unsigned int *ct,
143
                                                  const vpx_prob oldp,
144
                                                  vpx_prob *bestp, vpx_prob upd,
145
8.76M
                                                  int stepsize) {
146
8.76M
  int64_t i, old_b, new_b, update_b, savings, bestsavings;
147
8.76M
  int64_t newp;
148
8.76M
  const int64_t step_sign = *bestp > oldp ? -1 : 1;
149
8.76M
  const int64_t step = stepsize * step_sign;
150
8.76M
  const int64_t upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
151
8.76M
  const vpx_prob *newplist, *oldplist;
152
8.76M
  vpx_prob bestnewp;
153
8.76M
  oldplist = vp9_pareto8_full[oldp - 1];
154
8.76M
  old_b = cost_branch256(ct + 2 * PIVOT_NODE, oldp);
155
78.9M
  for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
156
70.1M
    old_b += cost_branch256(ct + 2 * i, oldplist[i - UNCONSTRAINED_NODES]);
157
158
8.76M
  bestsavings = 0;
159
8.76M
  bestnewp = oldp;
160
161
8.76M
  assert(stepsize > 0);
162
163
8.76M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
164
127M
    for (newp = *bestp; (newp - oldp) * step_sign < 0; newp += step) {
165
124M
      if (newp < 1 || newp > 255) continue;
166
124M
      newplist = vp9_pareto8_full[newp - 1];
167
124M
      new_b = cost_branch256(ct + 2 * PIVOT_NODE, (vpx_prob)newp);
168
1.12G
      for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
169
999M
        new_b += cost_branch256(ct + 2 * i, newplist[i - UNCONSTRAINED_NODES]);
170
124M
      update_b = prob_diff_update_cost((vpx_prob)newp, oldp) + upd_cost;
171
124M
      savings = old_b - new_b - update_b;
172
124M
      if (savings > bestsavings) {
173
3.28M
        bestsavings = savings;
174
3.28M
        bestnewp = (vpx_prob)newp;
175
3.28M
      }
176
124M
    }
177
2.39M
  }
178
179
8.76M
  *bestp = bestnewp;
180
8.76M
  return bestsavings;
181
8.76M
}
182
183
void vp9_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp,
184
7.18M
                               const unsigned int ct[2]) {
185
7.18M
  const vpx_prob upd = DIFF_UPDATE_PROB;
186
7.18M
  vpx_prob newp = get_binary_prob(ct[0], ct[1]);
187
7.18M
  const int64_t savings =
188
7.18M
      vp9_prob_diff_update_savings_search(ct, *oldp, &newp, upd);
189
7.18M
  assert(newp >= 1);
190
7.18M
  if (savings > 0) {
191
31.6k
    vpx_write(w, 1, upd);
192
31.6k
    vp9_write_prob_diff_update(w, newp, *oldp);
193
31.6k
    *oldp = newp;
194
7.14M
  } else {
195
7.14M
    vpx_write(w, 0, upd);
196
7.14M
  }
197
7.18M
}