Coverage Report

Created: 2026-10-28 08:13

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