Coverage Report

Created: 2026-07-25 07:52

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
22.7M
#define MIN_DELP_BITS 5
34
35
145M
static int recenter_nonneg(int v, int m) {
36
145M
  if (v > (m << 1))
37
39.0M
    return v;
38
106M
  else if (v >= m)
39
50.2M
    return ((v - m) << 1);
40
55.7M
  else
41
55.7M
    return ((m - v) << 1) - 1;
42
145M
}
43
44
145M
static int remap_prob(int v, int m) {
45
145M
  int i;
46
145M
  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
145M
    20,  21,  22,  23,  24,  25,  0,   26,  27,  28,  29,  30,  31,  32,  33,
50
145M
    34,  35,  36,  37,  1,   38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
51
145M
    48,  49,  2,   50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
52
145M
    3,   62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  4,   74,
53
145M
    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  5,   86,  87,  88,
54
145M
    89,  90,  91,  92,  93,  94,  95,  96,  97,  6,   98,  99,  100, 101, 102,
55
145M
    103, 104, 105, 106, 107, 108, 109, 7,   110, 111, 112, 113, 114, 115, 116,
56
145M
    117, 118, 119, 120, 121, 8,   122, 123, 124, 125, 126, 127, 128, 129, 130,
57
145M
    131, 132, 133, 9,   134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
58
145M
    145, 10,  146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11,
59
145M
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12,  170, 171,
60
145M
    172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13,  182, 183, 184, 185,
61
145M
    186, 187, 188, 189, 190, 191, 192, 193, 14,  194, 195, 196, 197, 198, 199,
62
145M
    200, 201, 202, 203, 204, 205, 15,  206, 207, 208, 209, 210, 211, 212, 213,
63
145M
    214, 215, 216, 217, 16,  218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
64
145M
    228, 229, 17,  230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
65
145M
    18,  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19,
66
145M
  };
67
145M
  v--;
68
145M
  m--;
69
145M
  assert(m >= 0);
70
145M
  if ((m << 1) <= MAX_PROB)
71
81.0M
    i = recenter_nonneg(v, m) - 1;
72
64.0M
  else
73
64.0M
    i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1;
74
75
145M
  assert(i >= 0 && (size_t)i < sizeof(map_table));
76
145M
  i = map_table[i];
77
145M
  return i;
78
145M
}
79
80
144M
static int prob_diff_update_cost(vpx_prob newp, vpx_prob oldp) {
81
144M
  int delp = remap_prob(newp, oldp);
82
144M
  return update_bits[delp] << VP9_PROB_COST_SHIFT;
83
144M
}
84
85
33.4k
static void encode_uniform(vpx_writer *w, int v) {
86
33.4k
  const int l = 8;
87
33.4k
  const int m = (1 << l) - 191;
88
33.4k
  if (v < m) {
89
14.6k
    vpx_write_literal(w, v, l - 1);
90
18.7k
  } else {
91
18.7k
    vpx_write_literal(w, m + ((v - m) >> 1), l - 1);
92
18.7k
    vpx_write_literal(w, (v - m) & 1, 1);
93
18.7k
  }
94
33.4k
}
95
96
590k
static INLINE int write_bit_gte(vpx_writer *w, int word, int test) {
97
590k
  vpx_write_literal(w, word >= test, 1);
98
590k
  return word >= test;
99
590k
}
100
101
403k
static void encode_term_subexp(vpx_writer *w, int word) {
102
403k
  if (!write_bit_gte(w, word, 16)) {
103
275k
    vpx_write_literal(w, word, 4);
104
275k
  } else if (!write_bit_gte(w, word, 32)) {
105
70.6k
    vpx_write_literal(w, word - 16, 4);
106
70.6k
  } else if (!write_bit_gte(w, word, 64)) {
107
24.4k
    vpx_write_literal(w, word - 32, 5);
108
33.4k
  } else {
109
33.4k
    encode_uniform(w, word - 64);
110
33.4k
  }
111
403k
}
112
113
403k
void vp9_write_prob_diff_update(vpx_writer *w, vpx_prob newp, vpx_prob oldp) {
114
403k
  const int delp = remap_prob(newp, oldp);
115
403k
  encode_term_subexp(w, delp);
116
403k
}
117
118
int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct,
119
                                            vpx_prob oldp, vpx_prob *bestp,
120
17.0M
                                            vpx_prob upd) {
121
17.0M
  const int64_t old_b = cost_branch256(ct, oldp);
122
17.0M
  int64_t bestsavings = 0;
123
17.0M
  vpx_prob newp, bestnewp = oldp;
124
17.0M
  const int step = *bestp > oldp ? -1 : 1;
125
17.0M
  const int upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
126
127
17.0M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
128
63.5M
    for (newp = *bestp; newp != oldp; newp += step) {
129
62.0M
      const int64_t new_b = cost_branch256(ct, newp);
130
62.0M
      const int64_t update_b = prob_diff_update_cost(newp, oldp) + upd_cost;
131
62.0M
      const int64_t savings = old_b - new_b - update_b;
132
62.0M
      if (savings > bestsavings) {
133
534k
        bestsavings = savings;
134
534k
        bestnewp = newp;
135
534k
      }
136
62.0M
    }
137
1.53M
  }
138
17.0M
  *bestp = bestnewp;
139
17.0M
  return bestsavings;
140
17.0M
}
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
5.73M
                                                  int stepsize) {
146
5.73M
  int64_t i, old_b, new_b, update_b, savings, bestsavings;
147
5.73M
  int64_t newp;
148
5.73M
  const int64_t step_sign = *bestp > oldp ? -1 : 1;
149
5.73M
  const int64_t step = stepsize * step_sign;
150
5.73M
  const int64_t upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
151
5.73M
  const vpx_prob *newplist, *oldplist;
152
5.73M
  vpx_prob bestnewp;
153
5.73M
  oldplist = vp9_pareto8_full[oldp - 1];
154
5.73M
  old_b = cost_branch256(ct + 2 * PIVOT_NODE, oldp);
155
51.6M
  for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
156
45.8M
    old_b += cost_branch256(ct + 2 * i, oldplist[i - UNCONSTRAINED_NODES]);
157
158
5.73M
  bestsavings = 0;
159
5.73M
  bestnewp = oldp;
160
161
5.73M
  assert(stepsize > 0);
162
163
5.73M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
164
84.2M
    for (newp = *bestp; (newp - oldp) * step_sign < 0; newp += step) {
165
82.6M
      if (newp < 1 || newp > 255) continue;
166
82.6M
      newplist = vp9_pareto8_full[newp - 1];
167
82.6M
      new_b = cost_branch256(ct + 2 * PIVOT_NODE, (vpx_prob)newp);
168
744M
      for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
169
661M
        new_b += cost_branch256(ct + 2 * i, newplist[i - UNCONSTRAINED_NODES]);
170
82.6M
      update_b = prob_diff_update_cost((vpx_prob)newp, oldp) + upd_cost;
171
82.6M
      savings = old_b - new_b - update_b;
172
82.6M
      if (savings > bestsavings) {
173
2.14M
        bestsavings = savings;
174
2.14M
        bestnewp = (vpx_prob)newp;
175
2.14M
      }
176
82.6M
    }
177
1.54M
  }
178
179
5.73M
  *bestp = bestnewp;
180
5.73M
  return bestsavings;
181
5.73M
}
182
183
void vp9_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp,
184
5.56M
                               const unsigned int ct[2]) {
185
5.56M
  const vpx_prob upd = DIFF_UPDATE_PROB;
186
5.56M
  vpx_prob newp = get_binary_prob(ct[0], ct[1]);
187
5.56M
  const int64_t savings =
188
5.56M
      vp9_prob_diff_update_savings_search(ct, *oldp, &newp, upd);
189
5.56M
  assert(newp >= 1);
190
5.56M
  if (savings > 0) {
191
20.5k
    vpx_write(w, 1, upd);
192
20.5k
    vp9_write_prob_diff_update(w, newp, *oldp);
193
20.5k
    *oldp = newp;
194
5.54M
  } else {
195
5.54M
    vpx_write(w, 0, upd);
196
5.54M
  }
197
5.56M
}