Coverage Report

Created: 2026-05-23 07:06

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